From e7b4bf7670cebeec201d9d5d9a63f8c64f188263 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 10 Feb 2026 22:15:17 +0100 Subject: [PATCH 1/5] feat: add custom response parser option and enhance binary data handling --- README.md | 49 +++++++++++++++++++++++++++++++++--- src/request-handler.ts | 4 ++- src/response-parser.ts | 25 +++++++++++------- src/types/request-handler.ts | 17 +++++++++++++ test/request-parser.spec.ts | 32 ++++++++++++++++++++--- 5 files changed, 110 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 83b71c68..64961cf0 100644 --- a/README.md +++ b/README.md @@ -572,6 +572,7 @@ You can also use all native [`fetch()` settings](https://developer.mozilla.org/e | refetchOnReconnect | `boolean` | `false` | When set to `true`, automatically revalidates (refetches) data when the browser regains internet connectivity after being offline. **This uses background revalidation to silently update data** without showing loading states to users. Helps ensure your application displays fresh data after network interruptions. Works by listening to the browser's `online` event. | | logger | `Logger` | `null` | You can additionally specify logger object with your custom logger to automatically log the errors to the console. It should contain at least `error` and `warn` functions. | | fetcher | `CustomFetcher` | `undefined` | A custom fetcher async function. By default, the native `fetch()` is used. If you use your own fetcher, default response parsing e.g. `await response.json()` call will be skipped. Your fetcher should return response object / data directly. | +| parser | `(response: Response) => Promise` | `undefined` | A custom response parser function. When provided, it replaces the built-in content-type based parsing entirely. Receives the raw `Response` object and should return the parsed data. Useful for handling custom formats like XML, CSV, or proprietary data. Can be set globally or per-request. | > 📋 **Additional Settings Available:** > The table above shows the most commonly used settings. Many more advanced configuration options are available and documented in their respective sections below, including: @@ -1753,23 +1754,65 @@ If the header is an HTTP-date, the delay will be calculated as the difference be Click to expand
-The `fetchff` plugin automatically handles response data transformation for any instance of `Response` returned by the `fetch()` (or a custom `fetcher`) based on the `Content-Type` header, ensuring that data is parsed correctly according to its format. +The `fetchff` plugin automatically handles response data transformation for any instance of `Response` returned by the `fetch()` (or a custom `fetcher`) based on the `Content-Type` header, ensuring that data is parsed correctly according to its format. It returns functions like `response.json()` that can be called idempotently without throwing errors or consuming the underlying stream multiple times. You can also use `parser` option to fully control returned response (useful for response streaming). ### **How It Works** - **JSON (`application/json`):** Parses the response as JSON. - **Form Data (`multipart/form-data`):** Parses the response as `FormData`. -- **Binary Data (`application/octet-stream`):** Parses the response as a `Blob`. +- **Binary Data (`application/octet-stream`, images, video, audio, pdf, zip):** Parses the response as an `ArrayBuffer`. Use `response.blob()` to get a `Blob`, or `response.bytes()` to get a `Uint8Array`. - **URL-encoded Form Data (`application/x-www-form-urlencoded`):** Parses the response as `FormData`. - **Text (`text/*`):** Parses the response as plain text. +- **Other/Custom types (XML, CSV, etc.):** Returns raw text. Use the `parser` option for custom parsing. -If the `Content-Type` header is missing or not recognized, the plugin defaults to attempting JSON parsing. If that fails, it will try to parse the response as text. +If the `Content-Type` header is missing or not recognized, the plugin defaults to returning text. If the text looks like JSON (starts with `{` or `[`), it will be auto-parsed as JSON. This approach ensures that the `fetchff` plugin can handle a variety of response formats, providing a flexible and reliable method for processing data from API requests. > ⚠️ **When using in Node.js:** > In Node.js, using FormData, Blob, or ReadableStream may require additional polyfills or will not work unless your fetch polyfill supports them. +### Custom `parser` Option + +You can provide a custom `parser` function to override the default content-type based parsing. This is useful for formats like XML, CSV, or any proprietary format. The `parser` can be set globally (via `createApiFetcher()` or `setDefaultConfig()`) or per-request. + +```typescript +import { fetchf } from 'fetchff'; + +// Example: Parse XML responses +const { data } = await fetchf('/api/data.xml', { + async parser(response) { + const text = await response.text(); + return new DOMParser().parseFromString(text, 'application/xml'); + }, +}); + +// Example: Parse CSV responses +const { data: csvData } = await fetchf('/api/report.csv', { + async parser(response) { + const text = await response.text(); + return text.split('\n').map((row) => row.split(',')); + }, +}); +``` + +You can also set it globally: + +```typescript +import { createApiFetcher } from 'fetchff'; + +const api = createApiFetcher({ + apiUrl: 'https://example.com/api', + parser: async (response) => { + const text = await response.text(); + return new DOMParser().parseFromString(text, 'application/xml'); + }, + endpoints: { + getReport: { url: '/report' }, + }, +}); +``` + ### `onResponse` Interceptor You can use the `onResponse` interceptor to customize how the response is handled before it reaches your application. This interceptor gives you access to the raw `Response` object, allowing you to transform the data or modify the response behavior based on your needs. diff --git a/src/request-handler.ts b/src/request-handler.ts index d4fb8673..7b047b8b 100644 --- a/src/request-handler.ts +++ b/src/request-handler.ts @@ -242,7 +242,9 @@ export async function fetchf< if (isObject(response)) { // Case 1: Native Response instance if (typeof Response === FUNCTION && response instanceof Response) { - response.data = await parseResponseData(response); + response.data = requestConfig.parser + ? await requestConfig.parser(response) + : await parseResponseData(response); } else if (fn) { // Case 2: Custom fetcher that returns a response object if (!('data' in response && 'body' in response)) { diff --git a/src/response-parser.ts b/src/response-parser.ts index c4e88364..b303b417 100644 --- a/src/response-parser.ts +++ b/src/response-parser.ts @@ -65,10 +65,14 @@ export async function parseResponseData< ) { data = await response.formData(); } else if ( - mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') && - typeof response.blob === FUNCTION + mimeType.startsWith('image/') || + mimeType.startsWith('video/') || + mimeType.startsWith('audio/') || + mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') || + mimeType.includes('pdf') || + mimeType.includes('zip') ) { - data = await response.blob(); // Parse as blob + data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types } else { data = await response.text(); @@ -191,13 +195,16 @@ export const prepareResponse = < statusText: response.statusText, // Convert methods to use arrow functions to preserve correct return types - blob: () => response.blob(), - json: () => response.json(), - text: () => response.text(), + blob: async () => + data instanceof ArrayBuffer ? new Blob([data]) : new Blob(), // Lazily construct Blob from ArrayBuffer + json: () => Promise.resolve(data) as Promise, // Return the already parsed JSON data + text: () => Promise.resolve(data) as Promise, // Return the already parsed text data clone: () => response.clone(), - arrayBuffer: () => response.arrayBuffer(), - formData: () => response.formData(), - bytes: () => response.bytes(), + arrayBuffer: async () => + data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly + formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData + bytes: async () => + data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(0), // Return bytes from ArrayBuffer // Enhance the response with extra information error, diff --git a/src/types/request-handler.ts b/src/types/request-handler.ts index 59e6dc12..32126f0c 100644 --- a/src/types/request-handler.ts +++ b/src/types/request-handler.ts @@ -671,6 +671,23 @@ export interface ExtendedRequestConfig< PathParams >; + /** + * A custom response parser function to handle response data parsing. + * When provided, this function is used instead of the default content-type based parsing. + * Useful for handling custom response formats like XML, CSV, or proprietary data formats. + * + * @example: + * // Parse XML responses + * const xmlParser = async (response: Response) => { + * const text = await response.text(); + * return new DOMParser().parseFromString(text, 'application/xml'); + * }; + * const { data } = await fetchf('/api/data.xml', { parser: xmlParser }); + * + * @default undefined (uses built-in content-type based parsing) + */ + parser?: (response: Response) => Promise; + /** * A custom fetcher instance to handle requests instead of the default implementation. * When `null`, the default fetch behavior is used. diff --git a/test/request-parser.spec.ts b/test/request-parser.spec.ts index 0b72d422..09144a3d 100644 --- a/test/request-parser.spec.ts +++ b/test/request-parser.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { parseResponseData, prepareResponse } from '../src/response-parser'; import type { FetchResponse, @@ -52,15 +53,37 @@ describe('parseData()', () => { expect(data).toEqual(expectedData); }); - it('should parse Blob when Content-Type is application/octet-stream', async () => { + it('should parse ArrayBuffer when Content-Type is application/octet-stream', async () => { (mockResponse.headers.get as jest.Mock).mockReturnValue( 'application/octet-stream', ); - const expectedData = new Blob(['test']); - (mockResponse.blob as jest.Mock).mockResolvedValue(expectedData); + const expectedArrayBuffer = new ArrayBuffer(8); + mockResponse.arrayBuffer = jest.fn().mockResolvedValue(expectedArrayBuffer); const data = await parseResponseData(mockResponse); - expect(data).toEqual(expectedData); + expect(data).toBeInstanceOf(ArrayBuffer); + expect(data).toEqual(expectedArrayBuffer); + }); + + it('should return a Blob from .blob() when binary ArrayBuffer is parsed', async () => { + // Use a real Response object to pass instanceof Response + const expectedArrayBuffer = new ArrayBuffer(8); + const realResponse = new Response(expectedArrayBuffer, { + status: 200, + headers: { 'Content-Type': 'application/octet-stream' }, + }); + // parseResponseData returns ArrayBuffer, but prepareResponse wraps it + const arrayBuffer = await parseResponseData(realResponse as any); + (realResponse as any).data = arrayBuffer; + const wrapped = prepareResponse(realResponse as any, { + cacheKey: 'test', + url: '/test', + method: 'GET', + }); + + const blob = await wrapped.blob(); + expect(blob).toBeInstanceOf(Blob); + expect(blob.size).toBe(expectedArrayBuffer.byteLength); }); it('should parse FormData when Content-Type is application/x-www-form-urlencoded', async () => { @@ -192,6 +215,7 @@ describe('prepareResponse()', () => { } as unknown as FetchResponse; const config = { ...baseConfig, + select: (data: any) => data.items, }; From b87cd75d1771bebd62e3485f43b5720068ba9f61 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 10 Feb 2026 22:41:52 +0100 Subject: [PATCH 2/5] feat: refactor response methods to return promises for consistency --- src/response-parser.ts | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/response-parser.ts b/src/response-parser.ts index b303b417..b1fcb856 100644 --- a/src/response-parser.ts +++ b/src/response-parser.ts @@ -195,17 +195,25 @@ export const prepareResponse = < statusText: response.statusText, // Convert methods to use arrow functions to preserve correct return types - blob: async () => - data instanceof ArrayBuffer ? new Blob([data]) : new Blob(), // Lazily construct Blob from ArrayBuffer - json: () => Promise.resolve(data) as Promise, // Return the already parsed JSON data - text: () => Promise.resolve(data) as Promise, // Return the already parsed text data + blob: () => + Promise.resolve( + data instanceof ArrayBuffer ? new Blob([data]) : new Blob(), + ), // Lazily construct Blob from ArrayBuffer + json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data + text: () => Promise.resolve(data as string), // Return the already parsed text data clone: () => response.clone(), - arrayBuffer: async () => - data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly - formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData - bytes: async () => - data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(0), // Return bytes from ArrayBuffer - + arrayBuffer: () => + Promise.resolve( + data instanceof ArrayBuffer ? data : new ArrayBuffer(0), + ), // Return the ArrayBuffer directly + formData: () => + Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData + bytes: () => + Promise.resolve( + new Uint8Array( + data instanceof ArrayBuffer ? data : new ArrayBuffer(0), + ), + ), // Enhance the response with extra information error, data, From edaa06f012bfb76e7a8a58ef6deeaa6d114bd50a Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 10 Feb 2026 22:42:35 +0100 Subject: [PATCH 3/5] chore: build --- dist/browser/index.global.js | 4 ++-- dist/browser/index.global.js.map | 2 +- dist/browser/index.mjs | 4 ++-- dist/browser/index.mjs.map | 2 +- dist/node/index.js | 4 ++-- dist/node/index.js.map | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dist/browser/index.global.js b/dist/browser/index.global.js index 6736400c..33b1220a 100644 --- a/dist/browser/index.global.js +++ b/dist/browser/index.global.js @@ -1,3 +1,3 @@ -var fetchff=(function(exports){'use strict';var yt=Object.defineProperty;var Rt=(e,t,r)=>t in e?yt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Rt(e,typeof t!="symbol"?t+"":t,r);var w="application/",J=w+"json",Ne="charset=utf-8",C="Content-Type",P="undefined",k="object",b="string",D="function",ae="AbortError",Se="TimeoutError",Q="GET",_e="HEAD",ne="reject";var Ue=10;function se(e){return e instanceof URLSearchParams}function d(e){return e!==null&&typeof e===k}function G(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Me(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{i=typeof i===D?i():i,i=i===null||i===void 0?"":i,r[r.length]=a(l)+"="+a(i);},s=(l,i,m=0)=>{if(m>=Ue)return r;let c,p,g;if(l)if(Array.isArray(i))for(c=0,p=i.length;c{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function oe(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function ge(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||se(e)?false:!!(d(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===D))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function De(e,t=0){return t>=Ue?e:e&&d(e)&&typeof e.data!==P?De(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(d(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function Ke(){return typeof window!==P&&typeof window.addEventListener===D}function ie(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Ee=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function I(e,t,...r){if(e){if(typeof e===D){let a=await e(t,...r);a&&d(t)&&d(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&d(t)&&d(n)&&Object.assign(t,n);}}}var ue=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var le=class extends ue{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var fe=600,W=1e3,Pt=fe*W,Te=Array(fe).fill(0).map(()=>[]),q=new Map,ce=0,x=null,ze=([e,t])=>{q.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},B=(e,t,r)=>{if(_(e),rPt||r%W!==0){q.set(e,[setTimeout(ze.bind(null,[e,t]),r)]);return}let a=r/W,n=(ce+a)%fe;Te[n].push([e,t]),q.set(e,n),x||(x=setInterval(()=>{ce=(ce+1)%fe;let s=Te[ce];for(let o=0;o{let t=q.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Te[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}q.delete(e),!q.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function Je(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),u=H.get(e),l=null;if(u){let m=u[0],c=u[3];if(!c&&o-u[2]{ke(e,ie(t+" aborted due to timeout",Se));},r),i}async function ke(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),me(e));}}function me(e){_(e),H.delete(e);}function Ge(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function pe(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function gt(e){Ze(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Dt(a);});}function xe(e){if(U.has(e))return;let t=$e.bind(null,e,true),r=Ye.get(e);if(r){let a=r(t);U.set(e,a);return}Ke()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Ze(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ve(e,t,r,a,n,s,o){let u=M.get(e);u?(u[0]=t,u[1]=h(),u[2]=We,u[3]=a,u[4]=n,u[5]=s,u[6]=o):M.set(e,[t,h(),We,a,n,s,o]),s&&xe("focus"),o&&xe("online"),a&&B("s:"+e,pe.bind(null,e,true),a*1e3);}function Dt(e){M.delete(e),_("s:"+e);}var $=new Map;function Et(e){let t=$.get(e);return t||(t=new Set,$.set(e,t)),t}function Tt(e,t){Et(e).add(t);}function bt(e,t){let r=$.get(e);r&&(r.delete(t),r.size===0&&$.delete(e));}function L(e,t){let r=$.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function xt(e,t){return e?(Tt(e,t),()=>{bt(e,t);}):N}var we=(Ee()?60:30)*1e3,Z={strategy:ne,timeout:we,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:we/30,maxDelay:we,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=G(e);return j({},t,Z)}function tt(){return {...Z}}function Ae(e,t){if(!t)return Xe(e,tt());let r=G(t),a=j(Z,r);return Xe(e,a)}function Xe(e,t){var i;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==_e&&(a=(i=t.body)!=null?i:t.data,a&&typeof a!==b&&ge(a)&&(a=JSON.stringify(a))),Ct(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Le(s,t.params),l=oe(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function Ct(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(se(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(ge(t))r=J+";"+Ne;else return;e instanceof Headers?e.has(C)||e.set(C,r):d(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),et("retry",e,t,r),et("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],u=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?u.concat(o):o.concat(u);}function et(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),u=A(s);a[e]={...o,...u};}else a[e]={...n,...s};}}var ye=new Map,F="|",Ie=64,rt=/[^\w\-_|/:@.?=&~%#]/g,at=/[^\w\-_|/:@.?=&~%#]/,At=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function V(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:u="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{i+=p+"="+c+"&";}),i.length>Ie&&(i=Y(i));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)i="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))i="AB"+o.byteLength;else {let c=d(o)?JSON.stringify(Me(o)):String(o);i=c.length>Ie?Y(c):c;}let m=n+F+a+F+u+F+l+F+i;return at.test(m)?m.replace(rt,""):m}function nt(e){return e.expiry?h()>e.expiry:false}function Re(e){return ye.get(e)}function Pe(e,t,r,a){if(r===0){de(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;ye.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&B("c:"+e,()=>{de(e,true);},s);}function de(e,t=false){if(t){let r=Re(e);if(!r||!nt(r))return}ye.delete(e);}async function qe(e,t,r){if(!e)return null;let a=Re(e);if(!a)return null;let n=d(t)?G(t):t,s={...a.data,data:n},o={...a,data:s};return ye.set(e,o),L(e,s),r&&r.refetch?await pe(e):null}function X(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||Z.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Re(e);return n?nt(n)?(de(e),null):n.data:null}function Be(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Pe(a,e,n,t.staleTime),L(a,e),me(a);let o=t._prevKey;o&&me(o);}}async function st(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===D)a=await e.formData();else if(r.includes(w+"octet-stream")&&typeof e.blob===D)a=await e.blob();else if(a=await e.text(),typeof a===b){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var Fe=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=qe.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===D&&e instanceof Response,u=e.data;a!==void 0&&(u==null||typeof u===k&&Object.keys(u).length===0)&&(e.data=u=a),t.flattenResponse&&(e.data=u=De(u)),t.select&&(e.data=u=t.select(u));let l=A(e.headers);return o?{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:()=>e.blob(),json:()=>e.json(),text:()=>e.text(),clone:()=>e.clone(),arrayBuffer:()=>e.arrayBuffer(),formData:()=>e.formData(),bytes:()=>e.bytes(),error:r,data:u,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(d(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,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 It(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 u=ot(r);if(u!==null)return u}let a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?ot(s):null}async function it(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:u}=t,l=0,i=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await I(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=V(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(u&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function lt(e,t,r){let a=await t(e),n=a.error;if(!n)return Be(a,r),a;r.onError&&await I(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&Bt(r,"FETCH ERROR",n),Be(a,r,true),!s||r.rejectCancelled){let u=r.strategy;if(u===ne)return Promise.reject(n);u==="silent"&&await new Promise(()=>null);}return a}function ct(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ae;}function Bt(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var Oe=Object.freeze({isFetching:true});async function he(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=X(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ae(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:u,staleTime:l,refetchOnFocus:i,refetchOnReconnect:m,pollingInterval:c=0}=r,p=u!==void 0||l!==void 0,g=!!(s||a||o||p||n||i||m),f=null;if(g&&(f=V(r)),f&&p){let R=X(f,u,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:ft=0,resetTimeout:mt}=E,ve=async(R=false,te=0)=>{te||(f&&!R&&(l?X(f,u,r)||(Pe(f,Oe,u,l),L(f,Oe)):L(f,Oe)),r.cacheKey=f);let O=r.url,dt=Je(f,O,a,o||0,!!n,!!(a&&(!te||mt))),T=r;T.signal=dt.signal;let re,y=null;try{r.onRequest&&(f&&o&&!te&&await null,await I(r.onRequest,T));let v=r.fetcher;if(y=v?await v(O,T):await fetch(O,T),d(y)&&(typeof Response===D&&y instanceof Response?y.data=await st(y):v&&("data"in y&&"body"in y||(y={data:y})),y.config=T,y.ok!==void 0&&!y.ok))throw new le(`${T.method} to ${O} failed! Status: ${y.status||null}`,T,y);re=Fe(y,T);let K=r.onResponse;K&&await I(K,re);}catch(v){let K=v;ct(K,y,T),re=Fe(y,T,K);}return re},pt=ft>0?(R=false)=>it((te,O)=>ve(R,O),E):ve,ee=(R=false)=>lt(R,pt,r),Qe=c?ut(ee,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):ee();return f&&(o&&Ge(f,Qe),(l||i||m)&&Ve(f,ee,void 0,l,ee,!!i,!!m)),Qe}function Ft(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],u=o||{url:String(n)},l=u.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let i=oe(l)?(o==null?void 0:o.url)===l?j(u,s):s:j(j(e,u),s);return he(l,i)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} -exports.abortRequest=ke;exports.addTimeout=B;exports.buildConfig=Ae;exports.createAbortError=ie;exports.createApiFetcher=Ft;exports.deleteCache=de;exports.fetchf=he;exports.fetchff=he;exports.generateCacheKey=V;exports.getCache=Re;exports.getCachedResponse=X;exports.getDefaultConfig=tt;exports.getInFlightPromise=be;exports.isSlowConnection=Ee;exports.mutate=qe;exports.removeRevalidators=gt;exports.revalidate=pe;exports.revalidateAll=$e;exports.setCache=Pe;exports.setDefaultConfig=wt;exports.setEventProvider=ht;exports.subscribe=xt;return exports;})({});//# sourceMappingURL=index.global.js.map +var fetchff=(function(exports){'use strict';var yt=Object.defineProperty;var Rt=(e,t,r)=>t in e?yt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Rt(e,typeof t!="symbol"?t+"":t,r);var w="application/",J=w+"json",Ne="charset=utf-8",C="Content-Type",P="undefined",k="object",b="string",T="function",ae="AbortError",Se="TimeoutError",Q="GET",_e="HEAD",ne="reject";var Ue=10;function se(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===k}function W(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Me(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(l)+"="+a(u);},s=(l,u,m=0)=>{if(m>=Ue)return r;let c,p,g;if(l)if(Array.isArray(u))for(c=0,p=u.length;c{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function oe(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function ge(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||se(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function De(e,t=0){return t>=Ue?e:e&&y(e)&&typeof e.data!==P?De(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(y(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function Ke(){return typeof window!==P&&typeof window.addEventListener===T}function ie(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Ee=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function B(e,t,...r){if(e){if(typeof e===T){let a=await e(t,...r);a&&y(t)&&y(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&y(t)&&y(n)&&Object.assign(t,n);}}}var ue=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var le=class extends ue{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var fe=600,G=1e3,Pt=fe*G,Te=Array(fe).fill(0).map(()=>[]),I=new Map,ce=0,x=null,ze=([e,t])=>{I.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},q=(e,t,r)=>{if(_(e),rPt||r%G!==0){I.set(e,[setTimeout(ze.bind(null,[e,t]),r)]);return}let a=r/G,n=(ce+a)%fe;Te[n].push([e,t]),I.set(e,n),x||(x=setInterval(()=>{ce=(ce+1)%fe;let s=Te[ce];for(let o=0;o{let t=I.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Te[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}I.delete(e),!I.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function Je(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),l=null;if(i){let m=i[0],c=i[3];if(!c&&o-i[2]{ke(e,ie(t+" aborted due to timeout",Se));},r),u}async function ke(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),me(e));}}function me(e){_(e),H.delete(e);}function We(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function pe(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function gt(e){Ze(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Dt(a);});}function xe(e){if(U.has(e))return;let t=$e.bind(null,e,true),r=Ye.get(e);if(r){let a=r(t);U.set(e,a);return}Ke()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Ze(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ve(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=Ge,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),Ge,a,n,s,o]),s&&xe("focus"),o&&xe("online"),a&&q("s:"+e,pe.bind(null,e,true),a*1e3);}function Dt(e){M.delete(e),_("s:"+e);}var $=new Map;function Et(e){let t=$.get(e);return t||(t=new Set,$.set(e,t)),t}function Tt(e,t){Et(e).add(t);}function bt(e,t){let r=$.get(e);r&&(r.delete(t),r.size===0&&$.delete(e));}function L(e,t){let r=$.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function xt(e,t){return e?(Tt(e,t),()=>{bt(e,t);}):N}var we=(Ee()?60:30)*1e3,Z={strategy:ne,timeout:we,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:we/30,maxDelay:we,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=W(e);return j({},t,Z)}function tt(){return {...Z}}function Ae(e,t){if(!t)return Xe(e,tt());let r=W(t),a=j(Z,r);return Xe(e,a)}function Xe(e,t){var u;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==_e&&(a=(u=t.body)!=null?u:t.data,a&&typeof a!==b&&ge(a)&&(a=JSON.stringify(a))),Ct(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Le(s,t.params),l=oe(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function Ct(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(se(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(ge(t))r=J+";"+Ne;else return;e instanceof Headers?e.has(C)||e.set(C,r):y(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),et("retry",e,t,r),et("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function et(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var ye=new Map,v="|",Be=64,rt=/[^\w\-_|/:@.?=&~%#]/g,at=/[^\w\-_|/:@.?=&~%#]/,At=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function V(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+c+"&";}),u.length>Be&&(u=Y(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let c=y(o)?JSON.stringify(Me(o)):String(o);u=c.length>Be?Y(c):c;}let m=n+v+a+v+i+v+l+v+u;return at.test(m)?m.replace(rt,""):m}function nt(e){return e.expiry?h()>e.expiry:false}function Re(e){return ye.get(e)}function Pe(e,t,r,a){if(r===0){de(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;ye.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&q("c:"+e,()=>{de(e,true);},s);}function de(e,t=false){if(t){let r=Re(e);if(!r||!nt(r))return}ye.delete(e);}async function Ie(e,t,r){if(!e)return null;let a=Re(e);if(!a)return null;let n=y(t)?W(t):t,s={...a.data,data:n},o={...a,data:s};return ye.set(e,o),L(e,s),r&&r.refetch?await pe(e):null}function X(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||Z.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Re(e);return n?nt(n)?(de(e),null):n.data:null}function qe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Pe(a,e,n,t.staleTime),L(a,e),me(a);let o=t._prevKey;o&&me(o);}}async function st(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(r.startsWith("image/")||r.startsWith("video/")||r.startsWith("audio/")||r.includes(w+"octet-stream")||r.includes("pdf")||r.includes("zip"))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===b){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var ve=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Ie.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===k&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=De(i)),t.select&&(e.data=i=t.select(i));let l=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,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 Bt(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 a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?ot(s):null}async function it(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,l=0,u=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await B(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=V(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(i&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function lt(e,t,r){let a=await t(e),n=a.error;if(!n)return qe(a,r),a;r.onError&&await B(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&qt(r,"FETCH ERROR",n),qe(a,r,true),!s||r.rejectCancelled){let i=r.strategy;if(i===ne)return Promise.reject(n);i==="silent"&&await new Promise(()=>null);}return a}function ct(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ae;}function qt(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var Fe=Object.freeze({isFetching:true});async function he(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=X(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ae(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:l,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:c=0}=r,p=i!==void 0||l!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=V(r)),f&&p){let R=X(f,i,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:ft=0,resetTimeout:mt}=E,Oe=async(R=false,te=0)=>{te||(f&&!R&&(l?X(f,i,r)||(Pe(f,Fe,i,l),L(f,Fe)):L(f,Fe)),r.cacheKey=f);let F=r.url,dt=Je(f,F,a,o||0,!!n,!!(a&&(!te||mt))),D=r;D.signal=dt.signal;let re,d=null;try{r.onRequest&&(f&&o&&!te&&await null,await B(r.onRequest,D));let O=r.fetcher;if(d=O?await O(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await st(d):O&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new le(`${D.method} to ${F} failed! Status: ${d.status||null}`,D,d);re=ve(d,D);let K=r.onResponse;K&&await B(K,re);}catch(O){let K=O;ct(K,d,D),re=ve(d,D,K);}return re},pt=ft>0?(R=false)=>it((te,F)=>Oe(R,F),E):Oe,ee=(R=false)=>lt(R,pt,r),Qe=c?ut(ee,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):ee();return f&&(o&&We(f,Qe),(l||u||m)&&Ve(f,ee,void 0,l,ee,!!u,!!m)),Qe}function vt(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},l=i.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let u=oe(l)?(o==null?void 0:o.url)===l?j(i,s):s:j(j(e,i),s);return he(l,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} +exports.abortRequest=ke;exports.addTimeout=q;exports.buildConfig=Ae;exports.createAbortError=ie;exports.createApiFetcher=vt;exports.deleteCache=de;exports.fetchf=he;exports.fetchff=he;exports.generateCacheKey=V;exports.getCache=Re;exports.getCachedResponse=X;exports.getDefaultConfig=tt;exports.getInFlightPromise=be;exports.isSlowConnection=Ee;exports.mutate=Ie;exports.removeRevalidators=gt;exports.revalidate=pe;exports.revalidateAll=$e;exports.setCache=Pe;exports.setDefaultConfig=wt;exports.setEventProvider=ht;exports.subscribe=xt;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 6d022f4a..fe9e5bed 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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') &&\n typeof response.blob === FUNCTION\n ) {\n data = await response.blob(); // Parse as blob\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () => response.blob(),\n json: () => response.json(),\n text: () => response.text(),\n clone: () => response.clone(),\n arrayBuffer: () => response.arrayBuffer(),\n formData: () => response.formData(),\n bytes: () => response.bytes(),\n\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = await parseResponseData(response);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.startsWith('image/') ||\n mimeType.startsWith('video/') ||\n mimeType.startsWith('audio/') ||\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') ||\n mimeType.includes('pdf') ||\n mimeType.includes('zip')\n ) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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 281457ad..e2f77762 100644 --- a/dist/browser/index.mjs +++ b/dist/browser/index.mjs @@ -1,3 +1,3 @@ -var yt=Object.defineProperty;var Rt=(e,t,r)=>t in e?yt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Rt(e,typeof t!="symbol"?t+"":t,r);var w="application/",J=w+"json",Ne="charset=utf-8",C="Content-Type",P="undefined",k="object",b="string",D="function",ae="AbortError",Se="TimeoutError",Q="GET",_e="HEAD",ne="reject";var Ue=10;function se(e){return e instanceof URLSearchParams}function d(e){return e!==null&&typeof e===k}function G(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Me(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{i=typeof i===D?i():i,i=i===null||i===void 0?"":i,r[r.length]=a(l)+"="+a(i);},s=(l,i,m=0)=>{if(m>=Ue)return r;let c,p,g;if(l)if(Array.isArray(i))for(c=0,p=i.length;c{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function oe(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function ge(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||se(e)?false:!!(d(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===D))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function De(e,t=0){return t>=Ue?e:e&&d(e)&&typeof e.data!==P?De(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(d(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function Ke(){return typeof window!==P&&typeof window.addEventListener===D}function ie(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Ee=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function I(e,t,...r){if(e){if(typeof e===D){let a=await e(t,...r);a&&d(t)&&d(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&d(t)&&d(n)&&Object.assign(t,n);}}}var ue=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var le=class extends ue{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var fe=600,W=1e3,Pt=fe*W,Te=Array(fe).fill(0).map(()=>[]),q=new Map,ce=0,x=null,ze=([e,t])=>{q.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},B=(e,t,r)=>{if(_(e),rPt||r%W!==0){q.set(e,[setTimeout(ze.bind(null,[e,t]),r)]);return}let a=r/W,n=(ce+a)%fe;Te[n].push([e,t]),q.set(e,n),x||(x=setInterval(()=>{ce=(ce+1)%fe;let s=Te[ce];for(let o=0;o{let t=q.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Te[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}q.delete(e),!q.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function Je(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),u=H.get(e),l=null;if(u){let m=u[0],c=u[3];if(!c&&o-u[2]{ke(e,ie(t+" aborted due to timeout",Se));},r),i}async function ke(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),me(e));}}function me(e){_(e),H.delete(e);}function Ge(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function pe(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function gt(e){Ze(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Dt(a);});}function xe(e){if(U.has(e))return;let t=$e.bind(null,e,true),r=Ye.get(e);if(r){let a=r(t);U.set(e,a);return}Ke()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Ze(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ve(e,t,r,a,n,s,o){let u=M.get(e);u?(u[0]=t,u[1]=h(),u[2]=We,u[3]=a,u[4]=n,u[5]=s,u[6]=o):M.set(e,[t,h(),We,a,n,s,o]),s&&xe("focus"),o&&xe("online"),a&&B("s:"+e,pe.bind(null,e,true),a*1e3);}function Dt(e){M.delete(e),_("s:"+e);}var $=new Map;function Et(e){let t=$.get(e);return t||(t=new Set,$.set(e,t)),t}function Tt(e,t){Et(e).add(t);}function bt(e,t){let r=$.get(e);r&&(r.delete(t),r.size===0&&$.delete(e));}function L(e,t){let r=$.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function xt(e,t){return e?(Tt(e,t),()=>{bt(e,t);}):N}var we=(Ee()?60:30)*1e3,Z={strategy:ne,timeout:we,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:we/30,maxDelay:we,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=G(e);return j({},t,Z)}function tt(){return {...Z}}function Ae(e,t){if(!t)return Xe(e,tt());let r=G(t),a=j(Z,r);return Xe(e,a)}function Xe(e,t){var i;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==_e&&(a=(i=t.body)!=null?i:t.data,a&&typeof a!==b&&ge(a)&&(a=JSON.stringify(a))),Ct(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Le(s,t.params),l=oe(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function Ct(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(se(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(ge(t))r=J+";"+Ne;else return;e instanceof Headers?e.has(C)||e.set(C,r):d(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),et("retry",e,t,r),et("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],u=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?u.concat(o):o.concat(u);}function et(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),u=A(s);a[e]={...o,...u};}else a[e]={...n,...s};}}var ye=new Map,F="|",Ie=64,rt=/[^\w\-_|/:@.?=&~%#]/g,at=/[^\w\-_|/:@.?=&~%#]/,At=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function V(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:u="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{i+=p+"="+c+"&";}),i.length>Ie&&(i=Y(i));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)i="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))i="AB"+o.byteLength;else {let c=d(o)?JSON.stringify(Me(o)):String(o);i=c.length>Ie?Y(c):c;}let m=n+F+a+F+u+F+l+F+i;return at.test(m)?m.replace(rt,""):m}function nt(e){return e.expiry?h()>e.expiry:false}function Re(e){return ye.get(e)}function Pe(e,t,r,a){if(r===0){de(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;ye.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&B("c:"+e,()=>{de(e,true);},s);}function de(e,t=false){if(t){let r=Re(e);if(!r||!nt(r))return}ye.delete(e);}async function qe(e,t,r){if(!e)return null;let a=Re(e);if(!a)return null;let n=d(t)?G(t):t,s={...a.data,data:n},o={...a,data:s};return ye.set(e,o),L(e,s),r&&r.refetch?await pe(e):null}function X(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||Z.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Re(e);return n?nt(n)?(de(e),null):n.data:null}function Be(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Pe(a,e,n,t.staleTime),L(a,e),me(a);let o=t._prevKey;o&&me(o);}}async function st(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===D)a=await e.formData();else if(r.includes(w+"octet-stream")&&typeof e.blob===D)a=await e.blob();else if(a=await e.text(),typeof a===b){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var Fe=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=qe.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===D&&e instanceof Response,u=e.data;a!==void 0&&(u==null||typeof u===k&&Object.keys(u).length===0)&&(e.data=u=a),t.flattenResponse&&(e.data=u=De(u)),t.select&&(e.data=u=t.select(u));let l=A(e.headers);return o?{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:()=>e.blob(),json:()=>e.json(),text:()=>e.text(),clone:()=>e.clone(),arrayBuffer:()=>e.arrayBuffer(),formData:()=>e.formData(),bytes:()=>e.bytes(),error:r,data:u,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(d(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,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 It(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 u=ot(r);if(u!==null)return u}let a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?ot(s):null}async function it(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:u}=t,l=0,i=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await I(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=V(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(u&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function lt(e,t,r){let a=await t(e),n=a.error;if(!n)return Be(a,r),a;r.onError&&await I(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&Bt(r,"FETCH ERROR",n),Be(a,r,true),!s||r.rejectCancelled){let u=r.strategy;if(u===ne)return Promise.reject(n);u==="silent"&&await new Promise(()=>null);}return a}function ct(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ae;}function Bt(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var Oe=Object.freeze({isFetching:true});async function he(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=X(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ae(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:u,staleTime:l,refetchOnFocus:i,refetchOnReconnect:m,pollingInterval:c=0}=r,p=u!==void 0||l!==void 0,g=!!(s||a||o||p||n||i||m),f=null;if(g&&(f=V(r)),f&&p){let R=X(f,u,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:ft=0,resetTimeout:mt}=E,ve=async(R=false,te=0)=>{te||(f&&!R&&(l?X(f,u,r)||(Pe(f,Oe,u,l),L(f,Oe)):L(f,Oe)),r.cacheKey=f);let O=r.url,dt=Je(f,O,a,o||0,!!n,!!(a&&(!te||mt))),T=r;T.signal=dt.signal;let re,y=null;try{r.onRequest&&(f&&o&&!te&&await null,await I(r.onRequest,T));let v=r.fetcher;if(y=v?await v(O,T):await fetch(O,T),d(y)&&(typeof Response===D&&y instanceof Response?y.data=await st(y):v&&("data"in y&&"body"in y||(y={data:y})),y.config=T,y.ok!==void 0&&!y.ok))throw new le(`${T.method} to ${O} failed! Status: ${y.status||null}`,T,y);re=Fe(y,T);let K=r.onResponse;K&&await I(K,re);}catch(v){let K=v;ct(K,y,T),re=Fe(y,T,K);}return re},pt=ft>0?(R=false)=>it((te,O)=>ve(R,O),E):ve,ee=(R=false)=>lt(R,pt,r),Qe=c?ut(ee,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):ee();return f&&(o&&Ge(f,Qe),(l||i||m)&&Ve(f,ee,void 0,l,ee,!!i,!!m)),Qe}function Ft(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],u=o||{url:String(n)},l=u.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let i=oe(l)?(o==null?void 0:o.url)===l?j(u,s):s:j(j(e,u),s);return he(l,i)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} -export{ke as abortRequest,B as addTimeout,Ae as buildConfig,ie as createAbortError,Ft as createApiFetcher,de as deleteCache,he as fetchf,he as fetchff,V as generateCacheKey,Re as getCache,X as getCachedResponse,tt as getDefaultConfig,be as getInFlightPromise,Ee as isSlowConnection,qe as mutate,gt as removeRevalidators,pe as revalidate,$e as revalidateAll,Pe as setCache,wt as setDefaultConfig,ht as setEventProvider,xt as subscribe};//# sourceMappingURL=index.mjs.map +var yt=Object.defineProperty;var Rt=(e,t,r)=>t in e?yt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Rt(e,typeof t!="symbol"?t+"":t,r);var w="application/",J=w+"json",Ne="charset=utf-8",C="Content-Type",P="undefined",k="object",b="string",T="function",ae="AbortError",Se="TimeoutError",Q="GET",_e="HEAD",ne="reject";var Ue=10;function se(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===k}function W(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Me(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(l)+"="+a(u);},s=(l,u,m=0)=>{if(m>=Ue)return r;let c,p,g;if(l)if(Array.isArray(u))for(c=0,p=u.length;c{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function oe(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function ge(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||se(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function De(e,t=0){return t>=Ue?e:e&&y(e)&&typeof e.data!==P?De(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(y(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function Ke(){return typeof window!==P&&typeof window.addEventListener===T}function ie(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Ee=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function B(e,t,...r){if(e){if(typeof e===T){let a=await e(t,...r);a&&y(t)&&y(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&y(t)&&y(n)&&Object.assign(t,n);}}}var ue=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var le=class extends ue{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var fe=600,G=1e3,Pt=fe*G,Te=Array(fe).fill(0).map(()=>[]),I=new Map,ce=0,x=null,ze=([e,t])=>{I.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},q=(e,t,r)=>{if(_(e),rPt||r%G!==0){I.set(e,[setTimeout(ze.bind(null,[e,t]),r)]);return}let a=r/G,n=(ce+a)%fe;Te[n].push([e,t]),I.set(e,n),x||(x=setInterval(()=>{ce=(ce+1)%fe;let s=Te[ce];for(let o=0;o{let t=I.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Te[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}I.delete(e),!I.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function Je(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),l=null;if(i){let m=i[0],c=i[3];if(!c&&o-i[2]{ke(e,ie(t+" aborted due to timeout",Se));},r),u}async function ke(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),me(e));}}function me(e){_(e),H.delete(e);}function We(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function pe(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function gt(e){Ze(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Dt(a);});}function xe(e){if(U.has(e))return;let t=$e.bind(null,e,true),r=Ye.get(e);if(r){let a=r(t);U.set(e,a);return}Ke()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Ze(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ve(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=Ge,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),Ge,a,n,s,o]),s&&xe("focus"),o&&xe("online"),a&&q("s:"+e,pe.bind(null,e,true),a*1e3);}function Dt(e){M.delete(e),_("s:"+e);}var $=new Map;function Et(e){let t=$.get(e);return t||(t=new Set,$.set(e,t)),t}function Tt(e,t){Et(e).add(t);}function bt(e,t){let r=$.get(e);r&&(r.delete(t),r.size===0&&$.delete(e));}function L(e,t){let r=$.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function xt(e,t){return e?(Tt(e,t),()=>{bt(e,t);}):N}var we=(Ee()?60:30)*1e3,Z={strategy:ne,timeout:we,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:we/30,maxDelay:we,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=W(e);return j({},t,Z)}function tt(){return {...Z}}function Ae(e,t){if(!t)return Xe(e,tt());let r=W(t),a=j(Z,r);return Xe(e,a)}function Xe(e,t){var u;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==_e&&(a=(u=t.body)!=null?u:t.data,a&&typeof a!==b&&ge(a)&&(a=JSON.stringify(a))),Ct(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Le(s,t.params),l=oe(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function Ct(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(se(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(ge(t))r=J+";"+Ne;else return;e instanceof Headers?e.has(C)||e.set(C,r):y(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),et("retry",e,t,r),et("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function et(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var ye=new Map,v="|",Be=64,rt=/[^\w\-_|/:@.?=&~%#]/g,at=/[^\w\-_|/:@.?=&~%#]/,At=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function V(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+c+"&";}),u.length>Be&&(u=Y(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let c=y(o)?JSON.stringify(Me(o)):String(o);u=c.length>Be?Y(c):c;}let m=n+v+a+v+i+v+l+v+u;return at.test(m)?m.replace(rt,""):m}function nt(e){return e.expiry?h()>e.expiry:false}function Re(e){return ye.get(e)}function Pe(e,t,r,a){if(r===0){de(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;ye.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&q("c:"+e,()=>{de(e,true);},s);}function de(e,t=false){if(t){let r=Re(e);if(!r||!nt(r))return}ye.delete(e);}async function Ie(e,t,r){if(!e)return null;let a=Re(e);if(!a)return null;let n=y(t)?W(t):t,s={...a.data,data:n},o={...a,data:s};return ye.set(e,o),L(e,s),r&&r.refetch?await pe(e):null}function X(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||Z.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Re(e);return n?nt(n)?(de(e),null):n.data:null}function qe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Pe(a,e,n,t.staleTime),L(a,e),me(a);let o=t._prevKey;o&&me(o);}}async function st(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(r.startsWith("image/")||r.startsWith("video/")||r.startsWith("audio/")||r.includes(w+"octet-stream")||r.includes("pdf")||r.includes("zip"))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===b){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var ve=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Ie.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===k&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=De(i)),t.select&&(e.data=i=t.select(i));let l=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,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 Bt(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 a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?ot(s):null}async function it(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,l=0,u=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await B(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=V(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(i&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function lt(e,t,r){let a=await t(e),n=a.error;if(!n)return qe(a,r),a;r.onError&&await B(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&qt(r,"FETCH ERROR",n),qe(a,r,true),!s||r.rejectCancelled){let i=r.strategy;if(i===ne)return Promise.reject(n);i==="silent"&&await new Promise(()=>null);}return a}function ct(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ae;}function qt(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var Fe=Object.freeze({isFetching:true});async function he(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=X(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ae(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:l,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:c=0}=r,p=i!==void 0||l!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=V(r)),f&&p){let R=X(f,i,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:ft=0,resetTimeout:mt}=E,Oe=async(R=false,te=0)=>{te||(f&&!R&&(l?X(f,i,r)||(Pe(f,Fe,i,l),L(f,Fe)):L(f,Fe)),r.cacheKey=f);let F=r.url,dt=Je(f,F,a,o||0,!!n,!!(a&&(!te||mt))),D=r;D.signal=dt.signal;let re,d=null;try{r.onRequest&&(f&&o&&!te&&await null,await B(r.onRequest,D));let O=r.fetcher;if(d=O?await O(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await st(d):O&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new le(`${D.method} to ${F} failed! Status: ${d.status||null}`,D,d);re=ve(d,D);let K=r.onResponse;K&&await B(K,re);}catch(O){let K=O;ct(K,d,D),re=ve(d,D,K);}return re},pt=ft>0?(R=false)=>it((te,F)=>Oe(R,F),E):Oe,ee=(R=false)=>lt(R,pt,r),Qe=c?ut(ee,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):ee();return f&&(o&&We(f,Qe),(l||u||m)&&Ve(f,ee,void 0,l,ee,!!u,!!m)),Qe}function vt(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},l=i.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let u=oe(l)?(o==null?void 0:o.url)===l?j(i,s):s:j(j(e,i),s);return he(l,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} +export{ke as abortRequest,q as addTimeout,Ae as buildConfig,ie as createAbortError,vt as createApiFetcher,de as deleteCache,he as fetchf,he as fetchff,V as generateCacheKey,Re as getCache,X as getCachedResponse,tt as getDefaultConfig,be as getInFlightPromise,Ee as isSlowConnection,Ie as mutate,gt as removeRevalidators,pe as revalidate,$e as revalidateAll,Pe as setCache,wt as setDefaultConfig,ht as setEventProvider,xt 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 b2c6a805..fcb697a1 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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') &&\n typeof response.blob === FUNCTION\n ) {\n data = await response.blob(); // Parse as blob\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () => response.blob(),\n json: () => response.json(),\n text: () => response.text(),\n clone: () => response.clone(),\n arrayBuffer: () => response.arrayBuffer(),\n formData: () => response.formData(),\n bytes: () => response.bytes(),\n\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = await parseResponseData(response);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.startsWith('image/') ||\n mimeType.startsWith('video/') ||\n mimeType.startsWith('audio/') ||\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') ||\n mimeType.includes('pdf') ||\n mimeType.includes('zip')\n ) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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 a340480b..f0f7d94b 100644 --- a/dist/node/index.js +++ b/dist/node/index.js @@ -1,3 +1,3 @@ -'use strict';var w="application/",z=w+"json",Qe="charset=utf-8",C="Content-Type",P="undefined",J="object",b="string",D="function",re="AbortError",Ne="TimeoutError",Q="GET",Se="HEAD",ae="reject";var He=10;function ne(e){return e instanceof URLSearchParams}function d(e){return e!==null&&typeof e===J}function k(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Ue(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{i=typeof i===D?i():i,i=i===null||i===void 0?"":i,r[r.length]=a(c)+"="+a(i);},s=(c,i,m=0)=>{if(m>=He)return r;let l,p,g;if(c)if(Array.isArray(i))for(l=0,p=i.length;l{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function se(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function he(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||ne(e)?false:!!(d(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===D))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function ge(e,t=0){return t>=He?e:e&&d(e)&&typeof e.data!==P?ge(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(d(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function je(){return typeof window!==P&&typeof window.addEventListener===D}function oe(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var De=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function I(e,t,...r){if(e){if(typeof e===D){let a=await e(t,...r);a&&d(t)&&d(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&d(t)&&d(n)&&Object.assign(t,n);}}}var ie=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}status;statusText;config;isCancelled};var ue=class extends ie{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var ce=600,G=1e3,dt=ce*G,Ee=Array(ce).fill(0).map(()=>[]),q=new Map,le=0,x=null,Ke=([e,t])=>{q.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch{}},B=(e,t,r)=>{if(_(e),rdt||r%G!==0){q.set(e,[setTimeout(Ke.bind(null,[e,t]),r)]);return}let a=r/G,n=(le+a)%ce;Ee[n].push([e,t]),q.set(e,n),x||(x=setInterval(()=>{le=(le+1)%ce;let s=Ee[le];for(let o=0;o{let t=q.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Ee[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}q.delete(e),!q.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function ze(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),u=H.get(e),c=null;if(u){let m=u[0],l=u[3];if(!l&&o-u[2]{Je(e,oe(t+" aborted due to timeout",Ne));},r),i}async function Je(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),fe(e));}}function fe(e){_(e),H.delete(e);}function ke(e,t){let r=H.get(e);r&&(r[4]=t);}function Te(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function me(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function Rt(e){$e(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Pt(a);});}function be(e){if(U.has(e))return;let t=Ye.bind(null,e,true),r=We.get(e);if(r){let a=r(t);U.set(e,a);return}je()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function $e(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ze(e,t,r,a,n,s,o){let u=M.get(e);u?(u[0]=t,u[1]=h(),u[2]=Ge,u[3]=a,u[4]=n,u[5]=s,u[6]=o):M.set(e,[t,h(),Ge,a,n,s,o]),s&&be("focus"),o&&be("online"),a&&B("s:"+e,me.bind(null,e,true),a*1e3);}function Pt(e){M.delete(e),_("s:"+e);}var Y=new Map;function ht(e){let t=Y.get(e);return t||(t=new Set,Y.set(e,t)),t}function gt(e,t){ht(e).add(t);}function Dt(e,t){let r=Y.get(e);r&&(r.delete(t),r.size===0&&Y.delete(e));}function L(e,t){let r=Y.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function Et(e,t){return e?(gt(e,t),()=>{Dt(e,t);}):N}var xe=(De()?60:30)*1e3,$={strategy:ae,timeout:xe,headers:{Accept:z+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:xe/30,maxDelay:xe,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function Tt(e){let t=k(e);return j({},t,$)}function et(){return {...$}}function Ce(e,t){if(!t)return Ve(e,et());let r=k(t),a=j($,r);return Ve(e,a)}function Ve(e,t){let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==Se&&(a=t.body??t.data,a&&typeof a!==b&&he(a)&&(a=JSON.stringify(a))),bt(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=Le(e,t.urlPathParams),o=Me(s,t.params),c=se(e)?"":t.baseURL||t.apiUrl||"";return t.url=c+o,t.method=r,t.credentials=n,t.body=a,t}function bt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(ne(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(he(t))r=z+";"+Qe;else return;e instanceof Headers?e.has(C)||e.set(C,r):d(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),Xe("retry",e,t,r),Xe("headers",e,t,r),we("onRequest",e,t,r),we("onResponse",e,t,r),we("onError",e,t,r),r}function we(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],u=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?u.concat(o):o.concat(u);}function Xe(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),u=A(s);a[e]={...o,...u};}else a[e]={...n,...s};}}var de=new Map,F="|",Ae=64,tt=/[^\w\-_|/:@.?=&~%#]/g,rt=/[^\w\-_|/:@.?=&~%#]/,xt=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function Z(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:u="same-origin"}=e,c="";if(s){let l;s instanceof Headers?l=A(s):l=s;let p=Object.keys(l),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{i+=p+"="+l+"&";}),i.length>Ae&&(i=W(i));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)i="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))i="AB"+o.byteLength;else {let l=d(o)?JSON.stringify(Ue(o)):String(o);i=l.length>Ae?W(l):l;}let m=n+F+a+F+u+F+c+F+i;return rt.test(m)?m.replace(tt,""):m}function at(e){return e.expiry?h()>e.expiry:false}function ye(e){return de.get(e)}function Re(e,t,r,a){if(r===0){pe(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;de.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&B("c:"+e,()=>{pe(e,true);},s);}function pe(e,t=false){if(t){let r=ye(e);if(!r||!at(r))return}de.delete(e);}async function Ie(e,t,r){if(!e)return null;let a=ye(e);if(!a)return null;let n=d(t)?k(t):t,s={...a.data,data:n},o={...a,data:s};return de.set(e,o),L(e,s),r&&r.refetch?await me(e):null}function V(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||$.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=ye(e);return n?at(n)?(pe(e),null):n.data:null}function qe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Re(a,e,n,t.staleTime),L(a,e),fe(a);let o=t._prevKey;o&&fe(o);}}async function nt(e){if(!e)return null;let t=e.headers?.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(z)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===D)a=await e.formData();else if(r.includes(w+"octet-stream")&&typeof e.blob===D)a=await e.blob();else if(a=await e.text(),typeof a===b){let n=a.trim();if(n.startsWith("{")&&n.endsWith("}")||n.startsWith("[")&&n.endsWith("]"))try{a=JSON.parse(n);}catch{}}}catch{a=null;}return a}var Be=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Ie.bind(null,n);if(!e)return {ok:false,error:r,data:a??null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===D&&e instanceof Response,u=e.data;a!==void 0&&(u==null||typeof u===J&&Object.keys(u).length===0)&&(e.data=u=a),t.flattenResponse&&(e.data=u=ge(u)),t.select&&(e.data=u=t.select(u));let c=A(e.headers);return o?{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:()=>e.blob(),json:()=>e.json(),text:()=>e.text(),clone:()=>e.clone(),arrayBuffer:()=>e.arrayBuffer(),formData:()=>e.formData(),bytes:()=>e.bytes(),error:r,data:u,headers:c,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(d(e)&&(e.error=r,e.headers=c,e.isFetching=false,e.mutate=s,e.isSuccess=e.ok&&!r,e.isError=!!r),e)};function st(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function wt(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 u=st(r);if(u!==null)return u}let a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?st(s):null}async function ot(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:u}=t,c=0,i=a,m=r>0?r:0,l;for(;c<=m;){if(c>0&&l){let f=l.config,E=f.onRetry;E&&(await I(E,l,c),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=Z(f,false)));}l=await e(c>0,c);let p=l.error;if(!p){if(u&&c0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function ut(e,t,r){let a=await t(e),n=a.error;if(!n)return qe(a,r),a;r.onError&&await I(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&At(r,"FETCH ERROR",n),qe(a,r,true),!s||r.rejectCancelled){let u=r.strategy;if(u===ae)return Promise.reject(n);u==="silent"&&await new Promise(()=>null);}return a}function lt(e,t,r){e.status=e.status||t?.status||0,e.statusText=e.statusText||t?.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===re;}function At(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var Fe=Object.freeze({isFetching:true});async function Pe(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=V(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ce(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:u,staleTime:c,refetchOnFocus:i,refetchOnReconnect:m,pollingInterval:l=0}=r,p=u!==void 0||c!==void 0,g=!!(s||a||o||p||n||i||m),f=null;if(g&&(f=Z(r)),f&&p){let R=V(f,u,r);if(R)return R}if(f&&o){let R=Te(f,o);if(R)return R}let E=r.retry||{},{retries:ct=0,resetTimeout:ft}=E,Oe=async(R=false,ee=0)=>{ee||(f&&!R&&(c?V(f,u,r)||(Re(f,Fe,u,c),L(f,Fe)):L(f,Fe)),r.cacheKey=f);let O=r.url,pt=ze(f,O,a,o||0,!!n,!!(a&&(!ee||ft))),T=r;T.signal=pt.signal;let te,y=null;try{r.onRequest&&(f&&o&&!ee&&await null,await I(r.onRequest,T));let v=r.fetcher;if(y=v?await v(O,T):await fetch(O,T),d(y)&&(typeof Response===D&&y instanceof Response?y.data=await nt(y):v&&("data"in y&&"body"in y||(y={data:y})),y.config=T,y.ok!==void 0&&!y.ok))throw new ue(`${T.method} to ${O} failed! Status: ${y.status||null}`,T,y);te=Be(y,T);let K=r.onResponse;K&&await I(K,te);}catch(v){let K=v;lt(K,y,T),te=Be(y,T,K);}return te},mt=ct>0?(R=false)=>ot((ee,O)=>Oe(R,O),E):Oe,X=(R=false)=>ut(R,mt,r),ve=l?it(X,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):X();return f&&(o&&ke(f,ve),(c||i||m)&&Ze(f,X,void 0,c,X,!!i,!!m)),ve}function It(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],u=o||{url:String(n)},c=u.url;if(c.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let i=se(c)?o?.url===c?j(u,s):s:j(j(e,u),s);return Pe(c,i)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} -exports.abortRequest=Je;exports.addTimeout=B;exports.buildConfig=Ce;exports.createAbortError=oe;exports.createApiFetcher=It;exports.deleteCache=pe;exports.fetchf=Pe;exports.fetchff=Pe;exports.generateCacheKey=Z;exports.getCache=ye;exports.getCachedResponse=V;exports.getDefaultConfig=et;exports.getInFlightPromise=Te;exports.isSlowConnection=De;exports.mutate=Ie;exports.removeRevalidators=Rt;exports.revalidate=me;exports.revalidateAll=Ye;exports.setCache=Re;exports.setDefaultConfig=Tt;exports.setEventProvider=yt;exports.subscribe=Et;//# sourceMappingURL=index.js.map +'use strict';var w="application/",z=w+"json",Qe="charset=utf-8",C="Content-Type",P="undefined",J="object",b="string",T="function",re="AbortError",Ne="TimeoutError",Q="GET",Se="HEAD",ae="reject";var He=10;function ne(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===J}function k(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Ue(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(c)+"="+a(u);},s=(c,u,m=0)=>{if(m>=He)return r;let l,p,g;if(c)if(Array.isArray(u))for(l=0,p=u.length;l{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function se(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function he(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||ne(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function ge(e,t=0){return t>=He?e:e&&y(e)&&typeof e.data!==P?ge(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(y(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function je(){return typeof window!==P&&typeof window.addEventListener===T}function oe(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var De=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function B(e,t,...r){if(e){if(typeof e===T){let a=await e(t,...r);a&&y(t)&&y(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&y(t)&&y(n)&&Object.assign(t,n);}}}var ie=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}status;statusText;config;isCancelled};var ue=class extends ie{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var ce=600,W=1e3,dt=ce*W,Ee=Array(ce).fill(0).map(()=>[]),I=new Map,le=0,x=null,Ke=([e,t])=>{I.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch{}},q=(e,t,r)=>{if(_(e),rdt||r%W!==0){I.set(e,[setTimeout(Ke.bind(null,[e,t]),r)]);return}let a=r/W,n=(le+a)%ce;Ee[n].push([e,t]),I.set(e,n),x||(x=setInterval(()=>{le=(le+1)%ce;let s=Ee[le];for(let o=0;o{let t=I.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Ee[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}I.delete(e),!I.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function ze(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),c=null;if(i){let m=i[0],l=i[3];if(!l&&o-i[2]{Je(e,oe(t+" aborted due to timeout",Ne));},r),u}async function Je(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),fe(e));}}function fe(e){_(e),H.delete(e);}function ke(e,t){let r=H.get(e);r&&(r[4]=t);}function Te(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function me(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function Rt(e){$e(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Pt(a);});}function be(e){if(U.has(e))return;let t=Ye.bind(null,e,true),r=Ge.get(e);if(r){let a=r(t);U.set(e,a);return}je()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function $e(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ze(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=We,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),We,a,n,s,o]),s&&be("focus"),o&&be("online"),a&&q("s:"+e,me.bind(null,e,true),a*1e3);}function Pt(e){M.delete(e),_("s:"+e);}var Y=new Map;function ht(e){let t=Y.get(e);return t||(t=new Set,Y.set(e,t)),t}function gt(e,t){ht(e).add(t);}function Dt(e,t){let r=Y.get(e);r&&(r.delete(t),r.size===0&&Y.delete(e));}function L(e,t){let r=Y.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function Et(e,t){return e?(gt(e,t),()=>{Dt(e,t);}):N}var xe=(De()?60:30)*1e3,$={strategy:ae,timeout:xe,headers:{Accept:z+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:xe/30,maxDelay:xe,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function Tt(e){let t=k(e);return j({},t,$)}function et(){return {...$}}function Ce(e,t){if(!t)return Ve(e,et());let r=k(t),a=j($,r);return Ve(e,a)}function Ve(e,t){let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==Se&&(a=t.body??t.data,a&&typeof a!==b&&he(a)&&(a=JSON.stringify(a))),bt(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=Le(e,t.urlPathParams),o=Me(s,t.params),c=se(e)?"":t.baseURL||t.apiUrl||"";return t.url=c+o,t.method=r,t.credentials=n,t.body=a,t}function bt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(ne(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(he(t))r=z+";"+Qe;else return;e instanceof Headers?e.has(C)||e.set(C,r):y(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),Xe("retry",e,t,r),Xe("headers",e,t,r),we("onRequest",e,t,r),we("onResponse",e,t,r),we("onError",e,t,r),r}function we(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function Xe(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var de=new Map,v="|",Ae=64,tt=/[^\w\-_|/:@.?=&~%#]/g,rt=/[^\w\-_|/:@.?=&~%#]/,xt=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function Z(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,c="";if(s){let l;s instanceof Headers?l=A(s):l=s;let p=Object.keys(l),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+l+"&";}),u.length>Ae&&(u=G(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let l=y(o)?JSON.stringify(Ue(o)):String(o);u=l.length>Ae?G(l):l;}let m=n+v+a+v+i+v+c+v+u;return rt.test(m)?m.replace(tt,""):m}function at(e){return e.expiry?h()>e.expiry:false}function ye(e){return de.get(e)}function Re(e,t,r,a){if(r===0){pe(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;de.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&q("c:"+e,()=>{pe(e,true);},s);}function pe(e,t=false){if(t){let r=ye(e);if(!r||!at(r))return}de.delete(e);}async function Be(e,t,r){if(!e)return null;let a=ye(e);if(!a)return null;let n=y(t)?k(t):t,s={...a.data,data:n},o={...a,data:s};return de.set(e,o),L(e,s),r&&r.refetch?await me(e):null}function V(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||$.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=ye(e);return n?at(n)?(pe(e),null):n.data:null}function Ie(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Re(a,e,n,t.staleTime),L(a,e),fe(a);let o=t._prevKey;o&&fe(o);}}async function nt(e){if(!e)return null;let t=e.headers?.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(z)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(r.startsWith("image/")||r.startsWith("video/")||r.startsWith("audio/")||r.includes(w+"octet-stream")||r.includes("pdf")||r.includes("zip"))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===b){let n=a.trim();if(n.startsWith("{")&&n.endsWith("}")||n.startsWith("[")&&n.endsWith("]"))try{a=JSON.parse(n);}catch{}}}catch{a=null;}return a}var qe=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Be.bind(null,n);if(!e)return {ok:false,error:r,data:a??null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===J&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=ge(i)),t.select&&(e.data=i=t.select(i));let c=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:c,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=c,e.isFetching=false,e.mutate=s,e.isSuccess=e.ok&&!r,e.isError=!!r),e)};function st(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function wt(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=st(r);if(i!==null)return i}let a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?st(s):null}async function ot(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,c=0,u=a,m=r>0?r:0,l;for(;c<=m;){if(c>0&&l){let f=l.config,E=f.onRetry;E&&(await B(E,l,c),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=Z(f,false)));}l=await e(c>0,c);let p=l.error;if(!p){if(i&&c0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function ut(e,t,r){let a=await t(e),n=a.error;if(!n)return Ie(a,r),a;r.onError&&await B(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&At(r,"FETCH ERROR",n),Ie(a,r,true),!s||r.rejectCancelled){let i=r.strategy;if(i===ae)return Promise.reject(n);i==="silent"&&await new Promise(()=>null);}return a}function lt(e,t,r){e.status=e.status||t?.status||0,e.statusText=e.statusText||t?.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===re;}function At(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var ve=Object.freeze({isFetching:true});async function Pe(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=V(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ce(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:c,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:l=0}=r,p=i!==void 0||c!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=Z(r)),f&&p){let R=V(f,i,r);if(R)return R}if(f&&o){let R=Te(f,o);if(R)return R}let E=r.retry||{},{retries:ct=0,resetTimeout:ft}=E,Fe=async(R=false,ee=0)=>{ee||(f&&!R&&(c?V(f,i,r)||(Re(f,ve,i,c),L(f,ve)):L(f,ve)),r.cacheKey=f);let F=r.url,pt=ze(f,F,a,o||0,!!n,!!(a&&(!ee||ft))),D=r;D.signal=pt.signal;let te,d=null;try{r.onRequest&&(f&&o&&!ee&&await null,await B(r.onRequest,D));let O=r.fetcher;if(d=O?await O(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await nt(d):O&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new ue(`${D.method} to ${F} failed! Status: ${d.status||null}`,D,d);te=qe(d,D);let K=r.onResponse;K&&await B(K,te);}catch(O){let K=O;lt(K,d,D),te=qe(d,D,K);}return te},mt=ct>0?(R=false)=>ot((ee,F)=>Fe(R,F),E):Fe,X=(R=false)=>ut(R,mt,r),Oe=l?it(X,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):X();return f&&(o&&ke(f,Oe),(c||u||m)&&Ze(f,X,void 0,c,X,!!u,!!m)),Oe}function Bt(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},c=i.url;if(c.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let u=se(c)?o?.url===c?j(i,s):s:j(j(e,i),s);return Pe(c,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} +exports.abortRequest=Je;exports.addTimeout=q;exports.buildConfig=Ce;exports.createAbortError=oe;exports.createApiFetcher=Bt;exports.deleteCache=pe;exports.fetchf=Pe;exports.fetchff=Pe;exports.generateCacheKey=Z;exports.getCache=ye;exports.getCachedResponse=V;exports.getDefaultConfig=et;exports.getInFlightPromise=Te;exports.isSlowConnection=De;exports.mutate=Be;exports.removeRevalidators=Rt;exports.revalidate=me;exports.revalidateAll=Ye;exports.setCache=Re;exports.setDefaultConfig=Tt;exports.setEventProvider=yt;exports.subscribe=Et;//# 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 b68d3441..194d3782 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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","contentType","mimeType","trimmed","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","_error","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') &&\n typeof response.blob === FUNCTION\n ) {\n data = await response.blob(); // Parse as blob\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () => response.blob(),\n json: () => response.json(),\n text: () => response.text(),\n clone: () => response.clone(),\n arrayBuffer: () => response.arrayBuffer(),\n formData: () => response.formData(),\n bytes: () => response.bytes(),\n\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = await parseResponseData(response);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","contentType","mimeType","trimmed","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","_error","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.startsWith('image/') ||\n mimeType.startsWith('video/') ||\n mimeType.startsWith('audio/') ||\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') ||\n mimeType.includes('pdf') ||\n mimeType.includes('zip')\n ) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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 From 49bdc6e8d337f60751944e9a9bb236e934629d1b Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 10 Feb 2026 23:37:27 +0100 Subject: [PATCH 4/5] perf: enhance utility functions for better performance + optimize bundle size --- src/api-handler.ts | 4 ++-- src/error-handler.ts | 21 ++----------------- src/interceptor-manager.ts | 18 +++++----------- src/pubsub-manager.ts | 13 ++++-------- src/request-handler.ts | 6 +++++- src/response-parser.ts | 9 +------- src/retry-handler.ts | 8 ++------ src/utils.ts | 42 +++++++++++++++----------------------- 8 files changed, 37 insertions(+), 84 deletions(-) diff --git a/src/api-handler.ts b/src/api-handler.ts index 1310e4a2..7e7180ef 100644 --- a/src/api-handler.ts +++ b/src/api-handler.ts @@ -55,7 +55,7 @@ function createApiFetcher< * @returns {Promise} */ function handleNonImplemented(endpointName: string): Promise { - console.error(`Add ${endpointName} to 'endpoints'.`); + console.error('Add ' + endpointName + " to 'endpoints'."); return Promise.resolve(null); } @@ -81,7 +81,7 @@ function createApiFetcher< // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery) if (url.startsWith('//')) { - throw new Error('Protocol-relative URLs are not allowed.'); + throw new Error('Protocol-relative URLs not allowed.'); } // Prevent potential Server-Side Request Forgery attack and leakage of credentials when same instance is used for external requests diff --git a/src/error-handler.ts b/src/error-handler.ts index d44ce81e..73ed9af3 100644 --- a/src/error-handler.ts +++ b/src/error-handler.ts @@ -52,8 +52,8 @@ export async function withErrorHandling< // Only handle the error if the request was not cancelled, or if it was cancelled and rejectCancelled is true. const isCancelled = error.isCancelled; - if (!isCancelled && requestConfig.logger) { - logger(requestConfig, 'FETCH ERROR', error as ResponseError); + if (!isCancelled && requestConfig.logger?.warn) { + requestConfig.logger.warn('FETCH ERROR', error as ResponseError); } // Handle cache and notifications FIRST (before strategy) @@ -105,20 +105,3 @@ export function enhanceError< error.response = response; error.isCancelled = error.name === ABORT_ERROR; } - -/** - * Logs messages or errors using the configured logger's `warn` method. - * - * @param {RequestConfig} reqConfig - Request config passed when making the request - * @param {...(string | ResponseError)} args - Messages or errors to log. - */ -function logger( - reqConfig: RequestConfig, - ...args: (string | ResponseError)[] -): void { - const logger = reqConfig.logger; - - if (logger && logger.warn) { - logger.warn(...args); - } -} diff --git a/src/interceptor-manager.ts b/src/interceptor-manager.ts index dcc979c6..e41780f6 100644 --- a/src/interceptor-manager.ts +++ b/src/interceptor-manager.ts @@ -25,22 +25,14 @@ export async function applyInterceptors< return; } - if (typeof interceptors === FUNCTION) { - const value = await (interceptors as InterceptorFunction)( - data, - ...args, - ); + const merge = (v: unknown) => + v && isObject(data) && isObject(v) && Object.assign(data, v); - if (value && isObject(data) && isObject(value)) { - Object.assign(data, value); - } + if (typeof interceptors === FUNCTION) { + merge(await (interceptors as InterceptorFunction)(data, ...args)); } else if (Array.isArray(interceptors)) { for (const interceptor of interceptors) { - const value = await interceptor(data, ...args); - - if (value && isObject(data) && isObject(value)) { - Object.assign(data, value); - } + merge(await interceptor(data, ...args)); } } } diff --git a/src/pubsub-manager.ts b/src/pubsub-manager.ts index 3c5a218f..f46da35c 100644 --- a/src/pubsub-manager.ts +++ b/src/pubsub-manager.ts @@ -27,20 +27,15 @@ type Listener = (response: T) => void; const listeners = new Map>(); -function ensureListenerSet(key: string) { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function addListener(key: string, fn: Listener): void { let set = listeners.get(key); if (!set) { - set = new Set(); - listeners.set(key, set); + listeners.set(key, (set = new Set())); } - return set; -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function addListener(key: string, fn: Listener): void { - ensureListenerSet(key).add(fn); + set.add(fn); } export function removeListener(key: string, fn: Listener) { diff --git a/src/request-handler.ts b/src/request-handler.ts index 7b047b8b..18fadc9f 100644 --- a/src/request-handler.ts +++ b/src/request-handler.ts @@ -267,7 +267,11 @@ export async function fetchf< // This is the pattern for fetch responses as per spec, but custom fetchers may not follow it so we check for `ok` property if (response.ok !== undefined && !response.ok) { throw new ResponseError( - `${requestConfig.method} to ${url} failed! Status: ${response.status || null}`, + requestConfig.method + + ' to ' + + url + + ' failed! Status: ' + + (response.status || null), requestConfig, response, ); diff --git a/src/response-parser.ts b/src/response-parser.ts index b1fcb856..168a3b46 100644 --- a/src/response-parser.ts +++ b/src/response-parser.ts @@ -64,14 +64,7 @@ export async function parseResponseData< typeof response.formData === FUNCTION ) { data = await response.formData(); - } else if ( - mimeType.startsWith('image/') || - mimeType.startsWith('video/') || - mimeType.startsWith('audio/') || - mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') || - mimeType.includes('pdf') || - mimeType.includes('zip') - ) { + } else if (/^(image|video|audio)\/|octet-stream|pdf|zip/.test(mimeType)) { data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types } else { data = await response.text(); diff --git a/src/retry-handler.ts b/src/retry-handler.ts index 14008655..c7e43b86 100644 --- a/src/retry-handler.ts +++ b/src/retry-handler.ts @@ -240,16 +240,12 @@ export async function getShouldStopRetrying< return true; } - let customDecision: boolean | null = null; - // Get custom decision if shouldRetry is provided if (shouldRetry) { const result = await shouldRetry(output, attempt); - customDecision = result; - // Decision cascade: - if (customDecision !== null) { - return !customDecision; + if (result !== null) { + return !result; } } diff --git a/src/utils.ts b/src/utils.ts index b64a59b2..ebc2ce40 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,6 +10,9 @@ import type { // Prevent stack overflow with recursion depth limit const MAX_DEPTH = 10; +const hasOwn = (o: any, k: string) => + Object.prototype.hasOwnProperty.call(o, k); + export function isSearchParams(data: unknown): boolean { return data instanceof URLSearchParams; } @@ -35,7 +38,7 @@ export function shallowSerialize(obj: Record): string { let result = ''; for (const key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (hasOwn(obj, key)) { result += key + ':' + obj[key]; } } @@ -54,9 +57,9 @@ export function shallowSerialize(obj: Record): string { * @returns A safe object without dangerous properties */ export function sanitizeObject>(obj: T): T { - const hasProto = Object.prototype.hasOwnProperty.call(obj, '__proto__'); - const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor'); - const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype'); + const hasProto = hasOwn(obj, '__proto__'); + const hasCtor = hasOwn(obj, 'constructor'); + const hasPrototype = hasOwn(obj, 'prototype'); if (!hasProto && !hasCtor && !hasPrototype) { return obj; @@ -81,17 +84,11 @@ export function sanitizeObject>(obj: T): T { * @returns {Object} - A new object with keys sorted in ascending order. */ export function sortObject(obj: Record): object { - const keys = Object.keys(obj); - - keys.sort(); - const sortedObj = {} as Record; - for (let i = 0, len = keys.length; i < len; i++) { - const key = keys[i]; - - sortedObj[key] = obj[key]; - } + Object.keys(obj) + .sort() + .forEach((k) => (sortedObj[k] = obj[k])); return sortedObj; } @@ -108,9 +105,7 @@ function appendQueryStringToUrl(baseUrl: string, queryString: string): string { return baseUrl; } - return baseUrl.includes('?') - ? `${baseUrl}&${queryString}` - : `${baseUrl}?${queryString}`; + return baseUrl + (baseUrl.includes('?') ? '&' : '?') + queryString; } /** @@ -210,7 +205,7 @@ export function replaceUrlPathParams( // Use a replacer function that avoids extra work return url.replace(/:([a-zA-Z0-9_]+)/g, (match, key) => { // Use hasOwnProperty for strict key existence check - if (Object.prototype.hasOwnProperty.call(params, key)) { + if (hasOwn(params, key)) { const value = params[key]; // Only replace if value is not undefined or null @@ -295,13 +290,8 @@ export function isJSONSerializable(value: any): boolean { return false; } -export async function delayInvocation(ms: number): Promise { - return new Promise((resolve) => - setTimeout(() => { - return resolve(true); - }, ms), - ); -} +export const delayInvocation = (ms: number): Promise => + new Promise((resolve) => setTimeout(resolve, ms, true)); /** * Recursively flattens the data object if it meets specific criteria. @@ -349,10 +339,10 @@ export function processHeaders( headers.forEach((value, key) => { headersObject[key.toLowerCase()] = value; }); - } else if (isObject(headers)) { + } else { // Handle plain object — use for...in to avoid Object.entries() allocation for (const key in headers) { - if (Object.prototype.hasOwnProperty.call(headers, key)) { + if (hasOwn(headers, key)) { headersObject[key.toLowerCase()] = headers[key]; } } From f7010c8fa1f40ccbefdac731dc444400272c716a Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 10 Feb 2026 23:41:36 +0100 Subject: [PATCH 5/5] chore: build --- dist/browser/index.global.js | 4 ++-- dist/browser/index.global.js.map | 2 +- dist/browser/index.mjs | 4 ++-- dist/browser/index.mjs.map | 2 +- dist/node/index.js | 4 ++-- dist/node/index.js.map | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dist/browser/index.global.js b/dist/browser/index.global.js index 33b1220a..d41072fe 100644 --- a/dist/browser/index.global.js +++ b/dist/browser/index.global.js @@ -1,3 +1,3 @@ -var fetchff=(function(exports){'use strict';var yt=Object.defineProperty;var Rt=(e,t,r)=>t in e?yt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Rt(e,typeof t!="symbol"?t+"":t,r);var w="application/",J=w+"json",Ne="charset=utf-8",C="Content-Type",P="undefined",k="object",b="string",T="function",ae="AbortError",Se="TimeoutError",Q="GET",_e="HEAD",ne="reject";var Ue=10;function se(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===k}function W(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Me(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(l)+"="+a(u);},s=(l,u,m=0)=>{if(m>=Ue)return r;let c,p,g;if(l)if(Array.isArray(u))for(c=0,p=u.length;c{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function oe(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function ge(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||se(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function De(e,t=0){return t>=Ue?e:e&&y(e)&&typeof e.data!==P?De(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(y(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function Ke(){return typeof window!==P&&typeof window.addEventListener===T}function ie(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Ee=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function B(e,t,...r){if(e){if(typeof e===T){let a=await e(t,...r);a&&y(t)&&y(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&y(t)&&y(n)&&Object.assign(t,n);}}}var ue=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var le=class extends ue{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var fe=600,G=1e3,Pt=fe*G,Te=Array(fe).fill(0).map(()=>[]),I=new Map,ce=0,x=null,ze=([e,t])=>{I.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},q=(e,t,r)=>{if(_(e),rPt||r%G!==0){I.set(e,[setTimeout(ze.bind(null,[e,t]),r)]);return}let a=r/G,n=(ce+a)%fe;Te[n].push([e,t]),I.set(e,n),x||(x=setInterval(()=>{ce=(ce+1)%fe;let s=Te[ce];for(let o=0;o{let t=I.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Te[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}I.delete(e),!I.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function Je(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),l=null;if(i){let m=i[0],c=i[3];if(!c&&o-i[2]{ke(e,ie(t+" aborted due to timeout",Se));},r),u}async function ke(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),me(e));}}function me(e){_(e),H.delete(e);}function We(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function pe(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function gt(e){Ze(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Dt(a);});}function xe(e){if(U.has(e))return;let t=$e.bind(null,e,true),r=Ye.get(e);if(r){let a=r(t);U.set(e,a);return}Ke()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Ze(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ve(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=Ge,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),Ge,a,n,s,o]),s&&xe("focus"),o&&xe("online"),a&&q("s:"+e,pe.bind(null,e,true),a*1e3);}function Dt(e){M.delete(e),_("s:"+e);}var $=new Map;function Et(e){let t=$.get(e);return t||(t=new Set,$.set(e,t)),t}function Tt(e,t){Et(e).add(t);}function bt(e,t){let r=$.get(e);r&&(r.delete(t),r.size===0&&$.delete(e));}function L(e,t){let r=$.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function xt(e,t){return e?(Tt(e,t),()=>{bt(e,t);}):N}var we=(Ee()?60:30)*1e3,Z={strategy:ne,timeout:we,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:we/30,maxDelay:we,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=W(e);return j({},t,Z)}function tt(){return {...Z}}function Ae(e,t){if(!t)return Xe(e,tt());let r=W(t),a=j(Z,r);return Xe(e,a)}function Xe(e,t){var u;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==_e&&(a=(u=t.body)!=null?u:t.data,a&&typeof a!==b&&ge(a)&&(a=JSON.stringify(a))),Ct(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Le(s,t.params),l=oe(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function Ct(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(se(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(ge(t))r=J+";"+Ne;else return;e instanceof Headers?e.has(C)||e.set(C,r):y(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),et("retry",e,t,r),et("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function et(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var ye=new Map,v="|",Be=64,rt=/[^\w\-_|/:@.?=&~%#]/g,at=/[^\w\-_|/:@.?=&~%#]/,At=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function V(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+c+"&";}),u.length>Be&&(u=Y(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let c=y(o)?JSON.stringify(Me(o)):String(o);u=c.length>Be?Y(c):c;}let m=n+v+a+v+i+v+l+v+u;return at.test(m)?m.replace(rt,""):m}function nt(e){return e.expiry?h()>e.expiry:false}function Re(e){return ye.get(e)}function Pe(e,t,r,a){if(r===0){de(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;ye.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&q("c:"+e,()=>{de(e,true);},s);}function de(e,t=false){if(t){let r=Re(e);if(!r||!nt(r))return}ye.delete(e);}async function Ie(e,t,r){if(!e)return null;let a=Re(e);if(!a)return null;let n=y(t)?W(t):t,s={...a.data,data:n},o={...a,data:s};return ye.set(e,o),L(e,s),r&&r.refetch?await pe(e):null}function X(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||Z.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Re(e);return n?nt(n)?(de(e),null):n.data:null}function qe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Pe(a,e,n,t.staleTime),L(a,e),me(a);let o=t._prevKey;o&&me(o);}}async function st(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(r.startsWith("image/")||r.startsWith("video/")||r.startsWith("audio/")||r.includes(w+"octet-stream")||r.includes("pdf")||r.includes("zip"))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===b){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var ve=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Ie.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===k&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=De(i)),t.select&&(e.data=i=t.select(i));let l=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,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 Bt(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 a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?ot(s):null}async function it(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,l=0,u=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await B(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=V(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(i&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function lt(e,t,r){let a=await t(e),n=a.error;if(!n)return qe(a,r),a;r.onError&&await B(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&qt(r,"FETCH ERROR",n),qe(a,r,true),!s||r.rejectCancelled){let i=r.strategy;if(i===ne)return Promise.reject(n);i==="silent"&&await new Promise(()=>null);}return a}function ct(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ae;}function qt(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var Fe=Object.freeze({isFetching:true});async function he(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=X(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ae(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:l,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:c=0}=r,p=i!==void 0||l!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=V(r)),f&&p){let R=X(f,i,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:ft=0,resetTimeout:mt}=E,Oe=async(R=false,te=0)=>{te||(f&&!R&&(l?X(f,i,r)||(Pe(f,Fe,i,l),L(f,Fe)):L(f,Fe)),r.cacheKey=f);let F=r.url,dt=Je(f,F,a,o||0,!!n,!!(a&&(!te||mt))),D=r;D.signal=dt.signal;let re,d=null;try{r.onRequest&&(f&&o&&!te&&await null,await B(r.onRequest,D));let O=r.fetcher;if(d=O?await O(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await st(d):O&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new le(`${D.method} to ${F} failed! Status: ${d.status||null}`,D,d);re=ve(d,D);let K=r.onResponse;K&&await B(K,re);}catch(O){let K=O;ct(K,d,D),re=ve(d,D,K);}return re},pt=ft>0?(R=false)=>it((te,F)=>Oe(R,F),E):Oe,ee=(R=false)=>lt(R,pt,r),Qe=c?ut(ee,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):ee();return f&&(o&&We(f,Qe),(l||u||m)&&Ve(f,ee,void 0,l,ee,!!u,!!m)),Qe}function vt(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},l=i.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let u=oe(l)?(o==null?void 0:o.url)===l?j(i,s):s:j(j(e,i),s);return he(l,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} -exports.abortRequest=ke;exports.addTimeout=q;exports.buildConfig=Ae;exports.createAbortError=ie;exports.createApiFetcher=vt;exports.deleteCache=de;exports.fetchf=he;exports.fetchff=he;exports.generateCacheKey=V;exports.getCache=Re;exports.getCachedResponse=X;exports.getDefaultConfig=tt;exports.getInFlightPromise=be;exports.isSlowConnection=Ee;exports.mutate=Ie;exports.removeRevalidators=gt;exports.revalidate=pe;exports.revalidateAll=$e;exports.setCache=Pe;exports.setDefaultConfig=wt;exports.setEventProvider=ht;exports.subscribe=xt;return exports;})({});//# sourceMappingURL=index.global.js.map +var fetchff=(function(exports){'use strict';var Rt=Object.defineProperty;var Pt=(e,t,r)=>t in e?Rt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Pt(e,typeof t!="symbol"?t+"":t,r);var O="application/",J=O+"json",Se="charset=utf-8",w="Content-Type",P="undefined",k="object",x="string",T="function",ne="AbortError",_e="TimeoutError",Q="GET",He="HEAD",se="reject";var Me=10,G=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function oe(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===k}function W(e){let t=G(e,"__proto__"),r=G(e,"constructor"),a=G(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Le(e){let t={};return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function Ue(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function Ke(e,t){if(!t)return e;if(oe(t)){let l=t.toString();return Ue(e,l)}let r=[],a=encodeURIComponent,n=(l,u)=>{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(l)+"="+a(u);},s=(l,u,m=0)=>{if(m>=Me)return r;let c,p,g;if(l)if(Array.isArray(u))for(c=0,p=u.length;c{if(G(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function ie(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function De(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||oe(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}var S=e=>new Promise(t=>setTimeout(t,e,true));function Ee(e,t=0){return t>=Me?e:e&&y(e)&&typeof e.data!==P?Ee(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else for(let r in e)G(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function ze(){return typeof window!==P&&typeof window.addEventListener===T}function ue(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Te=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function C(e,t,...r){if(!e)return;let a=n=>n&&y(t)&&y(n)&&Object.assign(t,n);if(typeof e===T)a(await e(t,...r));else if(Array.isArray(e))for(let n of e)a(await n(t,...r));}var le=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var ce=class extends le{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var me=600,Y=1e3,ht=me*Y,xe=Array(me).fill(0).map(()=>[]),B=new Map,fe=0,b=null,Je=([e,t])=>{B.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},I=(e,t,r)=>{if(_(e),rht||r%Y!==0){B.set(e,[setTimeout(Je.bind(null,[e,t]),r)]);return}let a=r/Y,n=(fe+a)%me;xe[n].push([e,t]),B.set(e,n),b||(b=setInterval(()=>{fe=(fe+1)%me;let s=xe[fe];for(let o=0;o{let t=B.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=xe[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}B.delete(e),!B.size&&b&&(clearInterval(b),b=null);}};var H=new Map;function ke(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),l=null;if(i){let m=i[0],c=i[3];if(!c&&o-i[2]{Ge(e,ue(t+" aborted due to timeout",_e));},r),u}async function Ge(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),pe(e));}}function pe(e){_(e),H.delete(e);}function We(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function de(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function Dt(e){Xe(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Et(a);});}function we(e){if(U.has(e))return;let t=Ve.bind(null,e,true),r=Ze.get(e);if(r){let a=r(t);U.set(e,a);return}ze()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Xe(e){let t=U.get(e);t&&(t(),U.delete(e));}function $e(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=Ye,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),Ye,a,n,s,o]),s&&we("focus"),o&&we("online"),a&&I("s:"+e,de.bind(null,e,true),a*1e3);}function Et(e){M.delete(e),_("s:"+e);}var V=new Map;function Tt(e,t){let r=V.get(e);r||V.set(e,r=new Set),r.add(t);}function xt(e,t){let r=V.get(e);r&&(r.delete(t),r.size===0&&V.delete(e));}function L(e,t){let r=V.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function bt(e,t){return e?(Tt(e,t),()=>{xt(e,t);}):N}var Ae=(Te()?60:30)*1e3,X={strategy:se,timeout:Ae,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Ae/30,maxDelay:Ae,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=W(e);return K({},t,X)}function rt(){return {...X}}function Be(e,t){if(!t)return et(e,rt());let r=W(t),a=K(X,r);return et(e,a)}function et(e,t){var u;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==He&&(a=(u=t.body)!=null?u:t.data,a&&typeof a!==x&&De(a)&&(a=JSON.stringify(a))),At(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Ke(s,t.params),l=ie(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function At(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(oe(t))r=O+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=O+"octet-stream";else if(De(t))r=J+";"+Se;else return;e instanceof Headers?e.has(w)||e.set(w,r):y(e)&&!Array.isArray(e)&&!e[w]&&(e[w]=r);}function K(e,t,r={}){return Object.assign(r,e,t),tt("retry",e,t,r),tt("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function tt(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var Re=new Map,q="|",Ie=64,at=/[^\w\-_|/:@.?=&~%#]/g,nt=/[^\w\-_|/:@.?=&~%#]/,Ct=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function $(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+c+"&";}),u.length>Ie&&(u=Z(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let c=y(o)?JSON.stringify(Le(o)):String(o);u=c.length>Ie?Z(c):c;}let m=n+q+a+q+i+q+l+q+u;return nt.test(m)?m.replace(at,""):m}function st(e){return e.expiry?h()>e.expiry:false}function Pe(e){return Re.get(e)}function he(e,t,r,a){if(r===0){ye(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;Re.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&I("c:"+e,()=>{ye(e,true);},s);}function ye(e,t=false){if(t){let r=Pe(e);if(!r||!st(r))return}Re.delete(e);}async function qe(e,t,r){if(!e)return null;let a=Pe(e);if(!a)return null;let n=y(t)?W(t):t,s={...a.data,data:n},o={...a,data:s};return Re.set(e,o),L(e,s),r&&r.refetch?await de(e):null}function ee(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||X.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Pe(e);return n?st(n)?(ye(e),null):n.data:null}function Fe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&he(a,e,n,t.staleTime),L(a,e),pe(a);let o=t._prevKey;o&&pe(o);}}async function ot(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(w);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(O+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(/^(image|video|audio)\/|octet-stream|pdf|zip/.test(r))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===x){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var ve=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=qe.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===k&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=Ee(i)),t.select&&(e.data=i=t.select(i));let l=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,e.isSuccess=e.ok&&!r,e.isError=!!r),e)};function it(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function Bt(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=it(r);if(i!==null)return i}let a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?it(s):null}async function ut(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,l=0,u=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await C(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=$(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(i&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function ct(e,t,r){var i;let a=await t(e),n=a.error;if(!n)return Fe(a,r),a;r.onError&&await C(r.onError,n);let s=n.isCancelled;if(!s&&((i=r.logger)!=null&&i.warn)&&r.logger.warn("FETCH ERROR",n),Fe(a,r,true),!s||r.rejectCancelled){let l=r.strategy;if(l===se)return Promise.reject(n);l==="silent"&&await new Promise(()=>null);}return a}function ft(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ne;}var Oe=Object.freeze({isFetching:true});async function ge(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=ee(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Be(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:l,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:c=0}=r,p=i!==void 0||l!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=$(r)),f&&p){let R=ee(f,i,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:mt=0,resetTimeout:pt}=E,Qe=async(R=false,re=0)=>{re||(f&&!R&&(l?ee(f,i,r)||(he(f,Oe,i,l),L(f,Oe)):L(f,Oe)),r.cacheKey=f);let F=r.url,yt=ke(f,F,a,o||0,!!n,!!(a&&(!re||pt))),D=r;D.signal=yt.signal;let ae,d=null;try{r.onRequest&&(f&&o&&!re&&await null,await C(r.onRequest,D));let v=r.fetcher;if(d=v?await v(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await ot(d):v&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new ce(D.method+" to "+F+" failed! Status: "+(d.status||null),D,d);ae=ve(d,D);let j=r.onResponse;j&&await C(j,ae);}catch(v){let j=v;ft(j,d,D),ae=ve(d,D,j);}return ae},dt=mt>0?(R=false)=>ut((re,F)=>Qe(R,F),E):Qe,te=(R=false)=>ct(R,dt,r),Ne=c?lt(te,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):te();return f&&(o&&We(f,Ne),(l||u||m)&&$e(f,te,void 0,l,te,!!u,!!m)),Ne}function qt(e){let t=e.endpoints;function r(n){return console.error("Add "+n+" to 'endpoints'."),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},l=i.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs not allowed.");let u=ie(l)?(o==null?void 0:o.url)===l?K(i,s):s:K(K(e,i),s);return ge(l,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} +exports.abortRequest=Ge;exports.addTimeout=I;exports.buildConfig=Be;exports.createAbortError=ue;exports.createApiFetcher=qt;exports.deleteCache=ye;exports.fetchf=ge;exports.fetchff=ge;exports.generateCacheKey=$;exports.getCache=Pe;exports.getCachedResponse=ee;exports.getDefaultConfig=rt;exports.getInFlightPromise=be;exports.isSlowConnection=Te;exports.mutate=qe;exports.removeRevalidators=Dt;exports.revalidate=de;exports.revalidateAll=Ve;exports.setCache=he;exports.setDefaultConfig=wt;exports.setEventProvider=gt;exports.subscribe=bt;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 fe9e5bed..268178c0 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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.startsWith('image/') ||\n mimeType.startsWith('video/') ||\n mimeType.startsWith('audio/') ||\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') ||\n mimeType.includes('pdf') ||\n mimeType.includes('zip')\n ) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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/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_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","key","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","bodyString","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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\nconst 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 const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const sortedObj = {} 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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport const delayInvocation = (ms: number): Promise =>\n new Promise((resolve) => setTimeout(resolve, ms, true));\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 if (hasOwn(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 && isObject(data) && isObject(v) && Object.assign(data, 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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 // 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 !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger?.warn) {\n requestConfig.logger.warn('FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || 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} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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 e2f77762..c2aa3eb9 100644 --- a/dist/browser/index.mjs +++ b/dist/browser/index.mjs @@ -1,3 +1,3 @@ -var yt=Object.defineProperty;var Rt=(e,t,r)=>t in e?yt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Rt(e,typeof t!="symbol"?t+"":t,r);var w="application/",J=w+"json",Ne="charset=utf-8",C="Content-Type",P="undefined",k="object",b="string",T="function",ae="AbortError",Se="TimeoutError",Q="GET",_e="HEAD",ne="reject";var Ue=10;function se(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===k}function W(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Me(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(l)+"="+a(u);},s=(l,u,m=0)=>{if(m>=Ue)return r;let c,p,g;if(l)if(Array.isArray(u))for(c=0,p=u.length;c{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function oe(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function ge(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||se(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function De(e,t=0){return t>=Ue?e:e&&y(e)&&typeof e.data!==P?De(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(y(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function Ke(){return typeof window!==P&&typeof window.addEventListener===T}function ie(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Ee=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function B(e,t,...r){if(e){if(typeof e===T){let a=await e(t,...r);a&&y(t)&&y(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&y(t)&&y(n)&&Object.assign(t,n);}}}var ue=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var le=class extends ue{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var fe=600,G=1e3,Pt=fe*G,Te=Array(fe).fill(0).map(()=>[]),I=new Map,ce=0,x=null,ze=([e,t])=>{I.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},q=(e,t,r)=>{if(_(e),rPt||r%G!==0){I.set(e,[setTimeout(ze.bind(null,[e,t]),r)]);return}let a=r/G,n=(ce+a)%fe;Te[n].push([e,t]),I.set(e,n),x||(x=setInterval(()=>{ce=(ce+1)%fe;let s=Te[ce];for(let o=0;o{let t=I.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Te[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}I.delete(e),!I.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function Je(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),l=null;if(i){let m=i[0],c=i[3];if(!c&&o-i[2]{ke(e,ie(t+" aborted due to timeout",Se));},r),u}async function ke(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),me(e));}}function me(e){_(e),H.delete(e);}function We(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function pe(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function gt(e){Ze(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Dt(a);});}function xe(e){if(U.has(e))return;let t=$e.bind(null,e,true),r=Ye.get(e);if(r){let a=r(t);U.set(e,a);return}Ke()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Ze(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ve(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=Ge,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),Ge,a,n,s,o]),s&&xe("focus"),o&&xe("online"),a&&q("s:"+e,pe.bind(null,e,true),a*1e3);}function Dt(e){M.delete(e),_("s:"+e);}var $=new Map;function Et(e){let t=$.get(e);return t||(t=new Set,$.set(e,t)),t}function Tt(e,t){Et(e).add(t);}function bt(e,t){let r=$.get(e);r&&(r.delete(t),r.size===0&&$.delete(e));}function L(e,t){let r=$.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function xt(e,t){return e?(Tt(e,t),()=>{bt(e,t);}):N}var we=(Ee()?60:30)*1e3,Z={strategy:ne,timeout:we,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:we/30,maxDelay:we,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=W(e);return j({},t,Z)}function tt(){return {...Z}}function Ae(e,t){if(!t)return Xe(e,tt());let r=W(t),a=j(Z,r);return Xe(e,a)}function Xe(e,t){var u;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==_e&&(a=(u=t.body)!=null?u:t.data,a&&typeof a!==b&&ge(a)&&(a=JSON.stringify(a))),Ct(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Le(s,t.params),l=oe(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function Ct(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(se(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(ge(t))r=J+";"+Ne;else return;e instanceof Headers?e.has(C)||e.set(C,r):y(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),et("retry",e,t,r),et("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function et(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var ye=new Map,v="|",Be=64,rt=/[^\w\-_|/:@.?=&~%#]/g,at=/[^\w\-_|/:@.?=&~%#]/,At=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function V(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+c+"&";}),u.length>Be&&(u=Y(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let c=y(o)?JSON.stringify(Me(o)):String(o);u=c.length>Be?Y(c):c;}let m=n+v+a+v+i+v+l+v+u;return at.test(m)?m.replace(rt,""):m}function nt(e){return e.expiry?h()>e.expiry:false}function Re(e){return ye.get(e)}function Pe(e,t,r,a){if(r===0){de(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;ye.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&q("c:"+e,()=>{de(e,true);},s);}function de(e,t=false){if(t){let r=Re(e);if(!r||!nt(r))return}ye.delete(e);}async function Ie(e,t,r){if(!e)return null;let a=Re(e);if(!a)return null;let n=y(t)?W(t):t,s={...a.data,data:n},o={...a,data:s};return ye.set(e,o),L(e,s),r&&r.refetch?await pe(e):null}function X(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||Z.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Re(e);return n?nt(n)?(de(e),null):n.data:null}function qe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Pe(a,e,n,t.staleTime),L(a,e),me(a);let o=t._prevKey;o&&me(o);}}async function st(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(r.startsWith("image/")||r.startsWith("video/")||r.startsWith("audio/")||r.includes(w+"octet-stream")||r.includes("pdf")||r.includes("zip"))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===b){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var ve=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Ie.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===k&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=De(i)),t.select&&(e.data=i=t.select(i));let l=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,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 Bt(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 a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?ot(s):null}async function it(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,l=0,u=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await B(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=V(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(i&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function lt(e,t,r){let a=await t(e),n=a.error;if(!n)return qe(a,r),a;r.onError&&await B(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&qt(r,"FETCH ERROR",n),qe(a,r,true),!s||r.rejectCancelled){let i=r.strategy;if(i===ne)return Promise.reject(n);i==="silent"&&await new Promise(()=>null);}return a}function ct(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ae;}function qt(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var Fe=Object.freeze({isFetching:true});async function he(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=X(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ae(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:l,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:c=0}=r,p=i!==void 0||l!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=V(r)),f&&p){let R=X(f,i,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:ft=0,resetTimeout:mt}=E,Oe=async(R=false,te=0)=>{te||(f&&!R&&(l?X(f,i,r)||(Pe(f,Fe,i,l),L(f,Fe)):L(f,Fe)),r.cacheKey=f);let F=r.url,dt=Je(f,F,a,o||0,!!n,!!(a&&(!te||mt))),D=r;D.signal=dt.signal;let re,d=null;try{r.onRequest&&(f&&o&&!te&&await null,await B(r.onRequest,D));let O=r.fetcher;if(d=O?await O(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await st(d):O&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new le(`${D.method} to ${F} failed! Status: ${d.status||null}`,D,d);re=ve(d,D);let K=r.onResponse;K&&await B(K,re);}catch(O){let K=O;ct(K,d,D),re=ve(d,D,K);}return re},pt=ft>0?(R=false)=>it((te,F)=>Oe(R,F),E):Oe,ee=(R=false)=>lt(R,pt,r),Qe=c?ut(ee,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):ee();return f&&(o&&We(f,Qe),(l||u||m)&&Ve(f,ee,void 0,l,ee,!!u,!!m)),Qe}function vt(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},l=i.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let u=oe(l)?(o==null?void 0:o.url)===l?j(i,s):s:j(j(e,i),s);return he(l,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} -export{ke as abortRequest,q as addTimeout,Ae as buildConfig,ie as createAbortError,vt as createApiFetcher,de as deleteCache,he as fetchf,he as fetchff,V as generateCacheKey,Re as getCache,X as getCachedResponse,tt as getDefaultConfig,be as getInFlightPromise,Ee as isSlowConnection,Ie as mutate,gt as removeRevalidators,pe as revalidate,$e as revalidateAll,Pe as setCache,wt as setDefaultConfig,ht as setEventProvider,xt as subscribe};//# sourceMappingURL=index.mjs.map +var Rt=Object.defineProperty;var Pt=(e,t,r)=>t in e?Rt(e,t,{enumerable:true,configurable:true,writable:true,value:r}):e[t]=r;var z=(e,t,r)=>Pt(e,typeof t!="symbol"?t+"":t,r);var O="application/",J=O+"json",Se="charset=utf-8",w="Content-Type",P="undefined",k="object",x="string",T="function",ne="AbortError",_e="TimeoutError",Q="GET",He="HEAD",se="reject";var Me=10,G=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function oe(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===k}function W(e){let t=G(e,"__proto__"),r=G(e,"constructor"),a=G(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Le(e){let t={};return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function Ue(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function Ke(e,t){if(!t)return e;if(oe(t)){let l=t.toString();return Ue(e,l)}let r=[],a=encodeURIComponent,n=(l,u)=>{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(l)+"="+a(u);},s=(l,u,m=0)=>{if(m>=Me)return r;let c,p,g;if(l)if(Array.isArray(u))for(c=0,p=u.length;c{if(G(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function ie(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function De(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||oe(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}var S=e=>new Promise(t=>setTimeout(t,e,true));function Ee(e,t=0){return t>=Me?e:e&&y(e)&&typeof e.data!==P?Ee(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else for(let r in e)G(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function ze(){return typeof window!==P&&typeof window.addEventListener===T}function ue(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Te=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function C(e,t,...r){if(!e)return;let a=n=>n&&y(t)&&y(n)&&Object.assign(t,n);if(typeof e===T)a(await e(t,...r));else if(Array.isArray(e))for(let n of e)a(await n(t,...r));}var le=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;z(this,"status");z(this,"statusText");z(this,"config");z(this,"isCancelled");this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}};var ce=class extends le{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var me=600,Y=1e3,ht=me*Y,xe=Array(me).fill(0).map(()=>[]),B=new Map,fe=0,b=null,Je=([e,t])=>{B.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch(r){}},I=(e,t,r)=>{if(_(e),rht||r%Y!==0){B.set(e,[setTimeout(Je.bind(null,[e,t]),r)]);return}let a=r/Y,n=(fe+a)%me;xe[n].push([e,t]),B.set(e,n),b||(b=setInterval(()=>{fe=(fe+1)%me;let s=xe[fe];for(let o=0;o{let t=B.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=xe[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}B.delete(e),!B.size&&b&&(clearInterval(b),b=null);}};var H=new Map;function ke(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),l=null;if(i){let m=i[0],c=i[3];if(!c&&o-i[2]{Ge(e,ue(t+" aborted due to timeout",_e));},r),u}async function Ge(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),pe(e));}}function pe(e){_(e),H.delete(e);}function We(e,t){let r=H.get(e);r&&(r[4]=t);}function be(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function de(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function Dt(e){Xe(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Et(a);});}function we(e){if(U.has(e))return;let t=Ve.bind(null,e,true),r=Ze.get(e);if(r){let a=r(t);U.set(e,a);return}ze()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Xe(e){let t=U.get(e);t&&(t(),U.delete(e));}function $e(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=Ye,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),Ye,a,n,s,o]),s&&we("focus"),o&&we("online"),a&&I("s:"+e,de.bind(null,e,true),a*1e3);}function Et(e){M.delete(e),_("s:"+e);}var V=new Map;function Tt(e,t){let r=V.get(e);r||V.set(e,r=new Set),r.add(t);}function xt(e,t){let r=V.get(e);r&&(r.delete(t),r.size===0&&V.delete(e));}function L(e,t){let r=V.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function bt(e,t){return e?(Tt(e,t),()=>{xt(e,t);}):N}var Ae=(Te()?60:30)*1e3,X={strategy:se,timeout:Ae,headers:{Accept:J+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Ae/30,maxDelay:Ae,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function wt(e){let t=W(e);return K({},t,X)}function rt(){return {...X}}function Be(e,t){if(!t)return et(e,rt());let r=W(t),a=K(X,r);return et(e,a)}function et(e,t){var u;let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==He&&(a=(u=t.body)!=null?u:t.data,a&&typeof a!==x&&De(a)&&(a=JSON.stringify(a))),At(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=je(e,t.urlPathParams),o=Ke(s,t.params),l=ie(e)?"":t.baseURL||t.apiUrl||"";return t.url=l+o,t.method=r,t.credentials=n,t.body=a,t}function At(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(oe(t))r=O+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=O+"octet-stream";else if(De(t))r=J+";"+Se;else return;e instanceof Headers?e.has(w)||e.set(w,r):y(e)&&!Array.isArray(e)&&!e[w]&&(e[w]=r);}function K(e,t,r={}){return Object.assign(r,e,t),tt("retry",e,t,r),tt("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function tt(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var Re=new Map,q="|",Ie=64,at=/[^\w\-_|/:@.?=&~%#]/g,nt=/[^\w\-_|/:@.?=&~%#]/,Ct=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function $(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,l="";if(s){let c;s instanceof Headers?c=A(s):c=s;let p=Object.keys(c),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+c+"&";}),u.length>Ie&&(u=Z(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let c=y(o)?JSON.stringify(Le(o)):String(o);u=c.length>Ie?Z(c):c;}let m=n+q+a+q+i+q+l+q+u;return nt.test(m)?m.replace(at,""):m}function st(e){return e.expiry?h()>e.expiry:false}function Pe(e){return Re.get(e)}function he(e,t,r,a){if(r===0){ye(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;Re.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&I("c:"+e,()=>{ye(e,true);},s);}function ye(e,t=false){if(t){let r=Pe(e);if(!r||!st(r))return}Re.delete(e);}async function qe(e,t,r){if(!e)return null;let a=Pe(e);if(!a)return null;let n=y(t)?W(t):t,s={...a.data,data:n},o={...a,data:s};return Re.set(e,o),L(e,s),r&&r.refetch?await de(e):null}function ee(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||X.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Pe(e);return n?st(n)?(ye(e),null):n.data:null}function Fe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&he(a,e,n,t.staleTime),L(a,e),pe(a);let o=t._prevKey;o&&pe(o);}}async function ot(e){var n;if(!e)return null;let t=(n=e.headers)==null?void 0:n.get(w);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(J)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(O+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(/^(image|video|audio)\/|octet-stream|pdf|zip/.test(r))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===x){let s=a.trim();if(s.startsWith("{")&&s.endsWith("}")||s.startsWith("[")&&s.endsWith("]"))try{a=JSON.parse(s);}catch(o){}}}catch(s){a=null;}return a}var ve=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=qe.bind(null,n);if(!e)return {ok:false,error:r,data:a!=null?a:null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===k&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=Ee(i)),t.select&&(e.data=i=t.select(i));let l=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:l,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=l,e.isFetching=false,e.mutate=s,e.isSuccess=e.ok&&!r,e.isError=!!r),e)};function it(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function Bt(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=it(r);if(i!==null)return i}let a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?it(s):null}async function ut(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,l=0,u=a,m=r>0?r:0,c;for(;l<=m;){if(l>0&&c){let f=c.config,E=f.onRetry;E&&(await C(E,c,l),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=$(f,false)));}c=await e(l>0,l);let p=c.error;if(!p){if(i&&l0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function ct(e,t,r){var i;let a=await t(e),n=a.error;if(!n)return Fe(a,r),a;r.onError&&await C(r.onError,n);let s=n.isCancelled;if(!s&&((i=r.logger)!=null&&i.warn)&&r.logger.warn("FETCH ERROR",n),Fe(a,r,true),!s||r.rejectCancelled){let l=r.strategy;if(l===se)return Promise.reject(n);l==="silent"&&await new Promise(()=>null);}return a}function ft(e,t,r){e.status=e.status||(t==null?void 0:t.status)||0,e.statusText=e.statusText||(t==null?void 0:t.statusText)||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ne;}var Oe=Object.freeze({isFetching:true});async function ge(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=ee(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Be(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:l,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:c=0}=r,p=i!==void 0||l!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=$(r)),f&&p){let R=ee(f,i,r);if(R)return R}if(f&&o){let R=be(f,o);if(R)return R}let E=r.retry||{},{retries:mt=0,resetTimeout:pt}=E,Qe=async(R=false,re=0)=>{re||(f&&!R&&(l?ee(f,i,r)||(he(f,Oe,i,l),L(f,Oe)):L(f,Oe)),r.cacheKey=f);let F=r.url,yt=ke(f,F,a,o||0,!!n,!!(a&&(!re||pt))),D=r;D.signal=yt.signal;let ae,d=null;try{r.onRequest&&(f&&o&&!re&&await null,await C(r.onRequest,D));let v=r.fetcher;if(d=v?await v(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await ot(d):v&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new ce(D.method+" to "+F+" failed! Status: "+(d.status||null),D,d);ae=ve(d,D);let j=r.onResponse;j&&await C(j,ae);}catch(v){let j=v;ft(j,d,D),ae=ve(d,D,j);}return ae},dt=mt>0?(R=false)=>ut((re,F)=>Qe(R,F),E):Qe,te=(R=false)=>ct(R,dt,r),Ne=c?lt(te,c,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):te();return f&&(o&&We(f,Ne),(l||u||m)&&$e(f,te,void 0,l,te,!!u,!!m)),Ne}function qt(e){let t=e.endpoints;function r(n){return console.error("Add "+n+" to 'endpoints'."),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},l=i.url;if(l.startsWith("//"))throw new Error("Protocol-relative URLs not allowed.");let u=ie(l)?(o==null?void 0:o.url)===l?K(i,s):s:K(K(e,i),s);return ge(l,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} +export{Ge as abortRequest,I as addTimeout,Be as buildConfig,ue as createAbortError,qt as createApiFetcher,ye as deleteCache,ge as fetchf,ge as fetchff,$ as generateCacheKey,Pe as getCache,ee as getCachedResponse,rt as getDefaultConfig,be as getInFlightPromise,Te as isSlowConnection,qe as mutate,Dt as removeRevalidators,de as revalidate,Ve as revalidateAll,he as setCache,wt as setDefaultConfig,gt as setEventProvider,bt 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 fcb697a1..dbe7c602 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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.startsWith('image/') ||\n mimeType.startsWith('video/') ||\n mimeType.startsWith('audio/') ||\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') ||\n mimeType.includes('pdf') ||\n mimeType.includes('zip')\n ) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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/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_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","key","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","__publicField","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","bodyString","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","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","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","_b","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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\nconst 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 const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const sortedObj = {} 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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport const delayInvocation = (ms: number): Promise =>\n new Promise((resolve) => setTimeout(resolve, ms, true));\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 if (hasOwn(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 && isObject(data) && isObject(v) && Object.assign(data, 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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 // 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 !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger?.warn) {\n requestConfig.logger.warn('FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || 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} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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 f0f7d94b..b3907964 100644 --- a/dist/node/index.js +++ b/dist/node/index.js @@ -1,3 +1,3 @@ -'use strict';var w="application/",z=w+"json",Qe="charset=utf-8",C="Content-Type",P="undefined",J="object",b="string",T="function",re="AbortError",Ne="TimeoutError",Q="GET",Se="HEAD",ae="reject";var He=10;function ne(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===J}function k(e){let t=Object.prototype.hasOwnProperty.call(e,"__proto__"),r=Object.prototype.hasOwnProperty.call(e,"constructor"),a=Object.prototype.hasOwnProperty.call(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Ue(e){let t=Object.keys(e);t.sort();let r={};for(let a=0,n=t.length;a{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(c)+"="+a(u);},s=(c,u,m=0)=>{if(m>=He)return r;let l,p,g;if(c)if(Array.isArray(u))for(l=0,p=u.length;l{if(Object.prototype.hasOwnProperty.call(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function se(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function he(e){let t=typeof e;return e==null?false:t===b||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||ne(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}async function S(e){return new Promise(t=>setTimeout(()=>t(true),e))}function ge(e,t=0){return t>=He?e:e&&y(e)&&typeof e.data!==P?ge(e.data,t+1):e}function A(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else if(y(e))for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function je(){return typeof window!==P&&typeof window.addEventListener===T}function oe(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var De=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function B(e,t,...r){if(e){if(typeof e===T){let a=await e(t,...r);a&&y(t)&&y(a)&&Object.assign(t,a);}else if(Array.isArray(e))for(let a of e){let n=await a(t,...r);n&&y(t)&&y(n)&&Object.assign(t,n);}}}var ie=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}status;statusText;config;isCancelled};var ue=class extends ie{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var ce=600,W=1e3,dt=ce*W,Ee=Array(ce).fill(0).map(()=>[]),I=new Map,le=0,x=null,Ke=([e,t])=>{I.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch{}},q=(e,t,r)=>{if(_(e),rdt||r%W!==0){I.set(e,[setTimeout(Ke.bind(null,[e,t]),r)]);return}let a=r/W,n=(le+a)%ce;Ee[n].push([e,t]),I.set(e,n),x||(x=setInterval(()=>{le=(le+1)%ce;let s=Ee[le];for(let o=0;o{let t=I.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Ee[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}I.delete(e),!I.size&&x&&(clearInterval(x),x=null);}};var H=new Map;function ze(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),c=null;if(i){let m=i[0],l=i[3];if(!l&&o-i[2]{Je(e,oe(t+" aborted due to timeout",Ne));},r),u}async function Je(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),fe(e));}}function fe(e){_(e),H.delete(e);}function ke(e,t){let r=H.get(e);r&&(r[4]=t);}function Te(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function me(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function Rt(e){$e(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&Pt(a);});}function be(e){if(U.has(e))return;let t=Ye.bind(null,e,true),r=Ge.get(e);if(r){let a=r(t);U.set(e,a);return}je()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function $e(e){let t=U.get(e);t&&(t(),U.delete(e));}function Ze(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=We,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),We,a,n,s,o]),s&&be("focus"),o&&be("online"),a&&q("s:"+e,me.bind(null,e,true),a*1e3);}function Pt(e){M.delete(e),_("s:"+e);}var Y=new Map;function ht(e){let t=Y.get(e);return t||(t=new Set,Y.set(e,t)),t}function gt(e,t){ht(e).add(t);}function Dt(e,t){let r=Y.get(e);r&&(r.delete(t),r.size===0&&Y.delete(e));}function L(e,t){let r=Y.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function Et(e,t){return e?(gt(e,t),()=>{Dt(e,t);}):N}var xe=(De()?60:30)*1e3,$={strategy:ae,timeout:xe,headers:{Accept:z+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:xe/30,maxDelay:xe,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function Tt(e){let t=k(e);return j({},t,$)}function et(){return {...$}}function Ce(e,t){if(!t)return Ve(e,et());let r=k(t),a=j($,r);return Ve(e,a)}function Ve(e,t){let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==Se&&(a=t.body??t.data,a&&typeof a!==b&&he(a)&&(a=JSON.stringify(a))),bt(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=Le(e,t.urlPathParams),o=Me(s,t.params),c=se(e)?"":t.baseURL||t.apiUrl||"";return t.url=c+o,t.method=r,t.credentials=n,t.body=a,t}function bt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(ne(t))r=w+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=w+"octet-stream";else if(he(t))r=z+";"+Qe;else return;e instanceof Headers?e.has(C)||e.set(C,r):y(e)&&!Array.isArray(e)&&!e[C]&&(e[C]=r);}function j(e,t,r={}){return Object.assign(r,e,t),Xe("retry",e,t,r),Xe("headers",e,t,r),we("onRequest",e,t,r),we("onResponse",e,t,r),we("onError",e,t,r),r}function we(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function Xe(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=A(n),i=A(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var de=new Map,v="|",Ae=64,tt=/[^\w\-_|/:@.?=&~%#]/g,rt=/[^\w\-_|/:@.?=&~%#]/,xt=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function Z(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===b?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,c="";if(s){let l;s instanceof Headers?l=A(s):l=s;let p=Object.keys(l),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+l+"&";}),u.length>Ae&&(u=G(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let l=y(o)?JSON.stringify(Ue(o)):String(o);u=l.length>Ae?G(l):l;}let m=n+v+a+v+i+v+c+v+u;return rt.test(m)?m.replace(tt,""):m}function at(e){return e.expiry?h()>e.expiry:false}function ye(e){return de.get(e)}function Re(e,t,r,a){if(r===0){pe(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;de.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&q("c:"+e,()=>{pe(e,true);},s);}function pe(e,t=false){if(t){let r=ye(e);if(!r||!at(r))return}de.delete(e);}async function Be(e,t,r){if(!e)return null;let a=ye(e);if(!a)return null;let n=y(t)?k(t):t,s={...a.data,data:n},o={...a,data:s};return de.set(e,o),L(e,s),r&&r.refetch?await me(e):null}function V(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||$.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=ye(e);return n?at(n)?(pe(e),null):n.data:null}function Ie(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Re(a,e,n,t.staleTime),L(a,e),fe(a);let o=t._prevKey;o&&fe(o);}}async function nt(e){if(!e)return null;let t=e.headers?.get(C);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(z)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(w+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(r.startsWith("image/")||r.startsWith("video/")||r.startsWith("audio/")||r.includes(w+"octet-stream")||r.includes("pdf")||r.includes("zip"))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===b){let n=a.trim();if(n.startsWith("{")&&n.endsWith("}")||n.startsWith("[")&&n.endsWith("]"))try{a=JSON.parse(n);}catch{}}}catch{a=null;}return a}var qe=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Be.bind(null,n);if(!e)return {ok:false,error:r,data:a??null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===J&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=ge(i)),t.select&&(e.data=i=t.select(i));let c=A(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:c,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=c,e.isFetching=false,e.mutate=s,e.isSuccess=e.ok&&!r,e.isError=!!r),e)};function st(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function wt(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=st(r);if(i!==null)return i}let a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?st(s):null}async function ot(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,c=0,u=a,m=r>0?r:0,l;for(;c<=m;){if(c>0&&l){let f=l.config,E=f.onRetry;E&&(await B(E,l,c),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=Z(f,false)));}l=await e(c>0,c);let p=l.error;if(!p){if(i&&c0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function ut(e,t,r){let a=await t(e),n=a.error;if(!n)return Ie(a,r),a;r.onError&&await B(r.onError,n);let s=n.isCancelled;if(!s&&r.logger&&At(r,"FETCH ERROR",n),Ie(a,r,true),!s||r.rejectCancelled){let i=r.strategy;if(i===ae)return Promise.reject(n);i==="silent"&&await new Promise(()=>null);}return a}function lt(e,t,r){e.status=e.status||t?.status||0,e.statusText=e.statusText||t?.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===re;}function At(e,...t){let r=e.logger;r&&r.warn&&r.warn(...t);}var ve=Object.freeze({isFetching:true});async function Pe(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=V(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ce(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:c,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:l=0}=r,p=i!==void 0||c!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=Z(r)),f&&p){let R=V(f,i,r);if(R)return R}if(f&&o){let R=Te(f,o);if(R)return R}let E=r.retry||{},{retries:ct=0,resetTimeout:ft}=E,Fe=async(R=false,ee=0)=>{ee||(f&&!R&&(c?V(f,i,r)||(Re(f,ve,i,c),L(f,ve)):L(f,ve)),r.cacheKey=f);let F=r.url,pt=ze(f,F,a,o||0,!!n,!!(a&&(!ee||ft))),D=r;D.signal=pt.signal;let te,d=null;try{r.onRequest&&(f&&o&&!ee&&await null,await B(r.onRequest,D));let O=r.fetcher;if(d=O?await O(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await nt(d):O&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new ue(`${D.method} to ${F} failed! Status: ${d.status||null}`,D,d);te=qe(d,D);let K=r.onResponse;K&&await B(K,te);}catch(O){let K=O;lt(K,d,D),te=qe(d,D,K);}return te},mt=ct>0?(R=false)=>ot((ee,F)=>Fe(R,F),E):Fe,X=(R=false)=>ut(R,mt,r),Oe=l?it(X,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):X();return f&&(o&&ke(f,Oe),(c||u||m)&&Ze(f,X,void 0,c,X,!!u,!!m)),Oe}function Bt(e){let t=e.endpoints;function r(n){return console.error(`Add ${n} to 'endpoints'.`),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},c=i.url;if(c.startsWith("//"))throw new Error("Protocol-relative URLs are not allowed.");let u=se(c)?o?.url===c?j(i,s):s:j(j(e,i),s);return Pe(c,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} -exports.abortRequest=Je;exports.addTimeout=q;exports.buildConfig=Ce;exports.createAbortError=oe;exports.createApiFetcher=Bt;exports.deleteCache=pe;exports.fetchf=Pe;exports.fetchff=Pe;exports.generateCacheKey=Z;exports.getCache=ye;exports.getCachedResponse=V;exports.getDefaultConfig=et;exports.getInFlightPromise=Te;exports.isSlowConnection=De;exports.mutate=Be;exports.removeRevalidators=Rt;exports.revalidate=me;exports.revalidateAll=Ye;exports.setCache=Re;exports.setDefaultConfig=Tt;exports.setEventProvider=yt;exports.subscribe=Et;//# sourceMappingURL=index.js.map +'use strict';var O="application/",z=O+"json",Ne="charset=utf-8",w="Content-Type",P="undefined",J="object",x="string",T="function",ae="AbortError",Se="TimeoutError",Q="GET",_e="HEAD",ne="reject";var Ue=10,k=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function se(e){return e instanceof URLSearchParams}function y(e){return e!==null&&typeof e===J}function G(e){let t=k(e,"__proto__"),r=k(e,"constructor"),a=k(e,"prototype");if(!t&&!r&&!a)return e;let n={...e};return t&&delete n.__proto__,r&&delete n.constructor,a&&delete n.prototype,n}function Me(e){let t={};return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function He(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function Le(e,t){if(!t)return e;if(se(t)){let c=t.toString();return He(e,c)}let r=[],a=encodeURIComponent,n=(c,u)=>{u=typeof u===T?u():u,u=u===null||u===void 0?"":u,r[r.length]=a(c)+"="+a(u);},s=(c,u,m=0)=>{if(m>=Ue)return r;let l,p,g;if(c)if(Array.isArray(u))for(l=0,p=u.length;l{if(k(r,n)){let s=r[n];if(s!=null)return encodeURIComponent(String(s))}return a})}function oe(e){return e.includes("://")}var h=()=>Date.now(),N=()=>{};function ge(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==P&&typeof globalThis.Buffer!==P&&globalThis.Buffer.isBuffer(e)||e instanceof Date||se(e)?false:!!(y(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===T))}var S=e=>new Promise(t=>setTimeout(t,e,true));function De(e,t=0){return t>=Ue?e:e&&y(e)&&typeof e.data!==P?De(e.data,t+1):e}function C(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,a)=>{t[a.toLowerCase()]=r;});else for(let r in e)k(e,r)&&(t[r.toLowerCase()]=e[r]);return t}function je(){return typeof window!==P&&typeof window.addEventListener===T}function ie(e,t){if(typeof DOMException!==P)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Ee=()=>{let e=typeof navigator!==P&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)};async function A(e,t,...r){if(!e)return;let a=n=>n&&y(t)&&y(n)&&Object.assign(t,n);if(typeof e===T)a(await e(t,...r));else if(Array.isArray(e))for(let n of e)a(await n(t,...r));}var ue=class extends Error{constructor(r,a,n){super(r);this.request=a;this.response=n;this.name="FetchError",this.status=n?n.status:0,this.statusText=n?n.statusText:"",this.config=a,this.isCancelled=false;}status;statusText;config;isCancelled};var le=class extends ue{constructor(t,r,a){super(t,r,a),this.name="ResponseError";}};var fe=600,W=1e3,yt=fe*W,Te=Array(fe).fill(0).map(()=>[]),B=new Map,ce=0,b=null,ze=([e,t])=>{B.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(N);}catch{}},I=(e,t,r)=>{if(_(e),ryt||r%W!==0){B.set(e,[setTimeout(ze.bind(null,[e,t]),r)]);return}let a=r/W,n=(ce+a)%fe;Te[n].push([e,t]),B.set(e,n),b||(b=setInterval(()=>{ce=(ce+1)%fe;let s=Te[ce];for(let o=0;o{let t=B.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Te[t],a=r.findIndex(([n])=>n===e);a!==-1&&r.splice(a,1);}B.delete(e),!B.size&&b&&(clearInterval(b),b=null);}};var H=new Map;function Je(e,t,r,a,n,s){if(!e)return new AbortController;let o=h(),i=H.get(e),c=null;if(i){let m=i[0],l=i[3];if(!l&&o-i[2]{ke(e,ie(t+" aborted due to timeout",Se));},r),u}async function ke(e,t=null){if(e){let r=H.get(e);r&&(t&&r[0].abort(t),me(e));}}function me(e){_(e),H.delete(e);}function Ge(e,t){let r=H.get(e);r&&(r[4]=t);}function xe(e,t){if(!e)return null;let r=H.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!n[r])return;n[1]=a;let s=t?n[4]:n[0];s&&Promise.resolve(s(t)).catch(N);});}async function pe(e,t=false){if(!e)return null;let r=M.get(e);if(r){r[1]=h();let a=t?r[4]:r[0];if(a)return await a(t)}return null}function Pt(e){Ve(e);let t=e==="focus"?5:6;M.forEach((r,a)=>{r[t]&&ht(a);});}function be(e){if(U.has(e))return;let t=Ze.bind(null,e,true),r=Ye.get(e);if(r){let a=r(t);U.set(e,a);return}je()&&(window.addEventListener(e,t),U.set(e,()=>window.removeEventListener(e,t)));}function Ve(e){let t=U.get(e);t&&(t(),U.delete(e));}function Xe(e,t,r,a,n,s,o){let i=M.get(e);i?(i[0]=t,i[1]=h(),i[2]=We,i[3]=a,i[4]=n,i[5]=s,i[6]=o):M.set(e,[t,h(),We,a,n,s,o]),s&&be("focus"),o&&be("online"),a&&I("s:"+e,pe.bind(null,e,true),a*1e3);}function ht(e){M.delete(e),_("s:"+e);}var Z=new Map;function gt(e,t){let r=Z.get(e);r||Z.set(e,r=new Set),r.add(t);}function Dt(e,t){let r=Z.get(e);r&&(r.delete(t),r.size===0&&Z.delete(e));}function L(e,t){let r=Z.get(e);if(r)if(r.size===1){let a=r.values().next().value;a(t);}else r.forEach(a=>a(t));}function Et(e,t){return e?(gt(e,t),()=>{Dt(e,t);}):N}var we=(Ee()?60:30)*1e3,V={strategy:ne,timeout:we,headers:{Accept:z+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:we/30,maxDelay:we,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504]}};function Tt(e){let t=G(e);return K({},t,V)}function tt(){return {...V}}function Ae(e,t){if(!t)return $e(e,tt());let r=G(t),a=K(V,r);return $e(e,a)}function $e(e,t){let r=t.method;r=r?r.toUpperCase():Q;let a;r!==Q&&r!==_e&&(a=t.body??t.data,a&&typeof a!==x&&ge(a)&&(a=JSON.stringify(a))),xt(t.headers,a);let n=t.withCredentials?"include":t.credentials,s=Ke(e,t.urlPathParams),o=Le(s,t.params),c=oe(e)?"":t.baseURL||t.apiUrl||"";return t.url=c+o,t.method=r,t.credentials=n,t.body=a,t}function xt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==P&&t instanceof Blob||typeof File!==P&&t instanceof File||typeof ReadableStream!==P&&t instanceof ReadableStream)return;let r;if(se(t))r=O+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=O+"octet-stream";else if(ge(t))r=z+";"+Ne;else return;e instanceof Headers?e.has(w)||e.set(w,r):y(e)&&!Array.isArray(e)&&!e[w]&&(e[w]=r);}function K(e,t,r={}){return Object.assign(r,e,t),et("retry",e,t,r),et("headers",e,t,r),Ce("onRequest",e,t,r),Ce("onResponse",e,t,r),Ce("onError",e,t,r),r}function Ce(e,t,r,a){let n=t[e],s=r[e];if(!n&&!s)return;if(!n){a[e]=s;return}if(!s){a[e]=n;return}let o=Array.isArray(n)?n:[n],i=Array.isArray(s)?s:[s];a[e]=e==="onResponse"?i.concat(o):o.concat(i);}function et(e,t,r,a){if(r[e]){let n=t[e],s=r[e];if(e==="headers"&&(n instanceof Headers||s instanceof Headers)){let o=C(n),i=C(s);a[e]={...o,...i};}else a[e]={...n,...s};}}var ye=new Map,q="|",Be=64,rt=/[^\w\-_|/:@.?=&~%#]/g,at=/[^\w\-_|/:@.?=&~%#]/,bt=new Set(["accept","accept-language","accept-encoding","authorization","content-type","referer","origin","user-agent","cookie","x-api-key","x-requested-with","x-client-id","x-tenant-id","x-user-id","x-app-version","x-feature-flag","x-device-id","x-platform","x-session-id","x-locale"]);function X(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:a="",method:n=Q,headers:s=null,body:o=null,credentials:i="same-origin"}=e,c="";if(s){let l;s instanceof Headers?l=C(s):l=s;let p=Object.keys(l),g=p.length;g>1&&p.sort();let f="";for(let E=0;E{u+=p+"="+l+"&";}),u.length>Be&&(u=Y(u));else if(typeof Blob!==P&&o instanceof Blob||typeof File!==P&&o instanceof File)u="BF"+o.size+o.type;else if(o instanceof ArrayBuffer||ArrayBuffer.isView(o))u="AB"+o.byteLength;else {let l=y(o)?JSON.stringify(Me(o)):String(o);u=l.length>Be?Y(l):l;}let m=n+q+a+q+i+q+c+q+u;return at.test(m)?m.replace(rt,""):m}function nt(e){return e.expiry?h()>e.expiry:false}function Re(e){return ye.get(e)}function Pe(e,t,r,a){if(r===0){de(e);return}let n=h(),s=r?r*1e3:0,o=a?a*1e3:0;ye.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+s}),s>0&&I("c:"+e,()=>{de(e,true);},s);}function de(e,t=false){if(t){let r=Re(e);if(!r||!nt(r))return}ye.delete(e);}async function Ie(e,t,r){if(!e)return null;let a=Re(e);if(!a)return null;let n=y(t)?G(t):t,s={...a.data,data:n},o={...a,data:s};return ye.set(e,o),L(e,s),r&&r.refetch?await pe(e):null}function $(e,t,r){if(!e||t===void 0||t===null)return null;let a=r.cacheBuster||V.cacheBuster;if(a&&a(r)||r.cache&&r.cache==="reload")return null;let n=Re(e);return n?nt(n)?(de(e),null):n.data:null}function qe(e,t,r=false){let a=t.cacheKey;if(a){let n=t.cacheTime,s=t.skipCache;n&&(!r||t.cacheErrors)&&!(s&&s(e,t))&&Pe(a,e,n,t.staleTime),L(a,e),me(a);let o=t._prevKey;o&&me(o);}}async function st(e){if(!e)return null;let t=e.headers?.get(w);t?t=t.toLowerCase().trim():t="";let r=t.split(";",1)[0],a;try{if(r.includes(z)||r.includes("+json"))a=await e.json();else if((r.includes("multipart/form-data")||r.includes(O+"x-www-form-urlencoded"))&&typeof e.formData===T)a=await e.formData();else if(/^(image|video|audio)\/|octet-stream|pdf|zip/.test(r))a=await e.arrayBuffer();else if(a=await e.text(),typeof a===x){let n=a.trim();if(n.startsWith("{")&&n.endsWith("}")||n.startsWith("[")&&n.endsWith("]"))try{a=JSON.parse(n);}catch{}}}catch{a=null;}return a}var Fe=(e,t,r=null)=>{let a=t.defaultResponse,n=t.cacheKey,s=Ie.bind(null,n);if(!e)return {ok:false,error:r,data:a??null,headers:null,config:t,mutate:s,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===T&&e instanceof Response,i=e.data;a!==void 0&&(i==null||typeof i===J&&Object.keys(i).length===0)&&(e.data=i=a),t.flattenResponse&&(e.data=i=De(i)),t.select&&(e.data=i=t.select(i));let c=C(e.headers);return o?{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:()=>Promise.resolve(i instanceof ArrayBuffer?new Blob([i]):new Blob),json:()=>Promise.resolve(i),text:()=>Promise.resolve(i),clone:()=>e.clone(),arrayBuffer:()=>Promise.resolve(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),formData:()=>Promise.resolve(i instanceof FormData?i:new FormData),bytes:()=>Promise.resolve(new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0))),error:r,data:i,headers:c,config:t,mutate:s,isFetching:false,isSuccess:e.ok&&!r,isError:!!r}:(y(e)&&(e.error=r,e.headers=c,e.isFetching=false,e.mutate=s,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 wt(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 a="ratelimit-reset",n=t[a+"-after"]||t["x-"+a+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let s=t[a+"-at"]||t["x-"+a+"-at"];return s?ot(s):null}async function it(e,t){let{retries:r=0,delay:a=0,backoff:n=1,maxDelay:s,retryOn:o=[],shouldRetry:i}=t,c=0,u=a,m=r>0?r:0,l;for(;c<=m;){if(c>0&&l){let f=l.config,E=f.onRetry;E&&(await A(E,l,c),f._isAutoKey&&(f._prevKey=f.cacheKey,f.cacheKey=X(f,false)));}l=await e(c>0,c);let p=l.error;if(!p){if(i&&c0&&await S(n),o=await e(),s++,!(a>0&&s>=a||!t||r&&r(o,s)));)await S(t);return o}async function lt(e,t,r){let a=await t(e),n=a.error;if(!n)return qe(a,r),a;r.onError&&await A(r.onError,n);let s=n.isCancelled;if(!s&&r.logger?.warn&&r.logger.warn("FETCH ERROR",n),qe(a,r,true),!s||r.rejectCancelled){let i=r.strategy;if(i===ne)return Promise.reject(n);i==="silent"&&await new Promise(()=>null);}return a}function ct(e,t,r){e.status=e.status||t?.status||0,e.statusText=e.statusText||t?.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===ae;}var ve=Object.freeze({isFetching:true});async function he(e,t=null){if(t&&typeof t.cacheKey=="string"){let R=$(t.cacheKey,t.cacheTime,t);if(R)return R}let r=Ae(e,t),{timeout:a,cancellable:n,cacheKey:s,dedupeTime:o,cacheTime:i,staleTime:c,refetchOnFocus:u,refetchOnReconnect:m,pollingInterval:l=0}=r,p=i!==void 0||c!==void 0,g=!!(s||a||o||p||n||u||m),f=null;if(g&&(f=X(r)),f&&p){let R=$(f,i,r);if(R)return R}if(f&&o){let R=xe(f,o);if(R)return R}let E=r.retry||{},{retries:ft=0,resetTimeout:mt}=E,Oe=async(R=false,te=0)=>{te||(f&&!R&&(c?$(f,i,r)||(Pe(f,ve,i,c),L(f,ve)):L(f,ve)),r.cacheKey=f);let F=r.url,dt=Je(f,F,a,o||0,!!n,!!(a&&(!te||mt))),D=r;D.signal=dt.signal;let re,d=null;try{r.onRequest&&(f&&o&&!te&&await null,await A(r.onRequest,D));let v=r.fetcher;if(d=v?await v(F,D):await fetch(F,D),y(d)&&(typeof Response===T&&d instanceof Response?d.data=D.parser?await D.parser(d):await st(d):v&&("data"in d&&"body"in d||(d={data:d})),d.config=D,d.ok!==void 0&&!d.ok))throw new le(D.method+" to "+F+" failed! Status: "+(d.status||null),D,d);re=Fe(d,D);let j=r.onResponse;j&&await A(j,re);}catch(v){let j=v;ct(j,d,D),re=Fe(d,D,j);}return re},pt=ft>0?(R=false)=>it((te,F)=>Oe(R,F),E):Oe,ee=(R=false)=>lt(R,pt,r),Qe=l?ut(ee,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay):ee();return f&&(o&&Ge(f,Qe),(c||u||m)&&Xe(f,ee,void 0,c,ee,!!u,!!m)),Qe}function At(e){let t=e.endpoints;function r(n){return console.error("Add "+n+" to 'endpoints'."),Promise.resolve(null)}let a={config:e,endpoints:t,async request(n,s={}){let o=t[n],i=o||{url:String(n)},c=i.url;if(c.startsWith("//"))throw new Error("Protocol-relative URLs not allowed.");let u=oe(c)?o?.url===c?K(i,s):s:K(K(e,i),s);return he(c,u)}};return new Proxy(a,{get(n,s){return s in a?a[s]:t[s]?a.request.bind(null,s):r.bind(null,s)}})} +exports.abortRequest=ke;exports.addTimeout=I;exports.buildConfig=Ae;exports.createAbortError=ie;exports.createApiFetcher=At;exports.deleteCache=de;exports.fetchf=he;exports.fetchff=he;exports.generateCacheKey=X;exports.getCache=Re;exports.getCachedResponse=$;exports.getDefaultConfig=tt;exports.getInFlightPromise=xe;exports.isSlowConnection=Ee;exports.mutate=Ie;exports.removeRevalidators=Pt;exports.revalidate=pe;exports.revalidateAll=Ze;exports.setCache=Pe;exports.setDefaultConfig=Tt;exports.setEventProvider=Rt;exports.subscribe=Et;//# 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 194d3782..f2ccf090 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/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_DEPTH","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","keys","sortedObj","i","len","key","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","k","v","buildParams","prefix","depth","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","ensureListenerSet","set","addListener","fn","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","cacheStr","bodyString","o","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","contentType","mimeType","trimmed","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","customDecision","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","logger","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","_error","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","mergedConfig","_target","prop"],"mappings":"aAAO,IAAMA,CAAAA,CAA2B,cAAA,CAE3BC,CAAAA,CAAmBD,CAAAA,CAA2B,MAAA,CAC9CE,EAAAA,CAAgB,eAAA,CAChBC,CAAAA,CAAe,cAAA,CAEfC,CAAAA,CAAY,WAAA,CACZC,CAAAA,CAAS,QAAA,CACTC,CAAAA,CAAS,QAAA,CACTC,CAAAA,CAAW,UAAA,CAEXC,EAAAA,CAAc,YAAA,CACdC,EAAAA,CAAgB,cAAA,CAEhBC,CAAAA,CAAM,KAAA,CACNC,EAAAA,CAAO,MAAA,CAEPC,EAAAA,CAAS,QAAA,CCPtB,IAAMC,EAAAA,CAAY,EAAA,CAEX,SAASC,EAAAA,CAAeC,CAAAA,CAAwB,CACrD,OAAOA,CAAAA,YAAgB,eACzB,CAQO,SAASC,CAAAA,CAASC,CAAAA,CAA0C,CACjE,OAAOA,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,GAAUZ,CAC5C,CA+BO,SAASa,CAAAA,CAA8CC,CAAAA,CAAW,CACvE,IAAMC,CAAAA,CAAW,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAKD,CAAAA,CAAK,WAAW,CAAA,CAChEE,CAAAA,CAAU,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAKF,CAAAA,CAAK,aAAa,CAAA,CACjEG,CAAAA,CAAe,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAKH,CAAAA,CAAK,WAAW,CAAA,CAE1E,GAAI,CAACC,CAAAA,EAAY,CAACC,CAAAA,EAAW,CAACC,CAAAA,CAC5B,OAAOH,CAAAA,CAGT,IAAMI,CAAAA,CAAU,CAAE,GAAGJ,CAAI,CAAA,CAEzB,OAAIC,CAAAA,EAAU,OAAOG,CAAAA,CAAQ,SAAA,CACzBF,CAAAA,EAAS,OAAQE,CAAAA,CAAgB,WAAA,CACjCD,CAAAA,EAAc,OAAOC,CAAAA,CAAQ,SAAA,CAE1BA,CACT,CAWO,SAASC,EAAAA,CAAWL,CAAAA,CAAkC,CAC3D,IAAMM,CAAAA,CAAO,MAAA,CAAO,IAAA,CAAKN,CAAG,CAAA,CAE5BM,CAAAA,CAAK,IAAA,EAAK,CAEV,IAAMC,CAAAA,CAAY,EAAC,CAEnB,IAAA,IAASC,CAAAA,CAAI,CAAA,CAAGC,CAAAA,CAAMH,CAAAA,CAAK,MAAA,CAAQE,CAAAA,CAAIC,CAAAA,CAAKD,CAAAA,EAAAA,CAAK,CAC/C,IAAME,CAAAA,CAAMJ,CAAAA,CAAKE,CAAC,CAAA,CAElBD,CAAAA,CAAUG,CAAG,CAAA,CAAIV,CAAAA,CAAIU,CAAG,EAC1B,CAEA,OAAOH,CACT,CASA,SAASI,EAAAA,CAAuBC,CAAAA,CAAiBC,CAAAA,CAA6B,CAC5E,OAAKA,CAAAA,CAIED,CAAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,CACvB,CAAA,EAAGA,CAAO,CAAA,CAAA,EAAIC,CAAW,CAAA,CAAA,CACzB,CAAA,EAAGD,CAAO,CAAA,CAAA,EAAIC,CAAW,CAAA,CAAA,CALpBD,CAMX,CASO,SAASE,EAAAA,CAAkBC,CAAAA,CAAaC,CAAAA,CAA6B,CAC1E,GAAI,CAACA,CAAAA,CACH,OAAOD,CAAAA,CAIT,GAAIpB,EAAAA,CAAeqB,CAAM,CAAA,CAAG,CAC1B,IAAMC,CAAAA,CAAqBD,CAAAA,CAAO,QAAA,EAAS,CAE3C,OAAOL,EAAAA,CAAuBI,CAAAA,CAAKE,CAAkB,CACvD,CAGA,IAAMC,CAAAA,CAAc,EAAC,CACfC,CAAAA,CAAS,kBAAA,CACTC,CAAAA,CAAM,CAACC,CAAAA,CAAWC,CAAAA,GAAW,CACjCA,CAAAA,CAAI,OAAOA,CAAAA,GAAMlC,CAAAA,CAAWkC,CAAAA,EAAE,CAAIA,CAAAA,CAClCA,CAAAA,CAAIA,CAAAA,GAAM,IAAA,EAAYA,CAAAA,GAAM,MAAA,CAAX,EAAA,CAA4BA,CAAAA,CAC7CJ,CAAAA,CAAEA,CAAAA,CAAE,MAAM,CAAA,CAAIC,CAAAA,CAAOE,CAAC,CAAA,CAAI,GAAA,CAAMF,CAAAA,CAAOG,CAAC,EAC1C,CAAA,CAEMC,CAAAA,CAAc,CAACC,CAAAA,CAAgBxB,CAAAA,CAAUyB,CAAAA,CAAQ,CAAA,GAAM,CAE3D,GAAIA,CAAAA,EAAS/B,EAAAA,CACX,OAAOwB,CAAAA,CAGT,IAAIV,CAAAA,CAAWC,CAAAA,CAAaC,CAAAA,CAE5B,GAAIc,CAAAA,CACF,GAAI,KAAA,CAAM,OAAA,CAAQxB,CAAG,CAAA,CACnB,IAAKQ,CAAAA,CAAI,CAAA,CAAGC,CAAAA,CAAMT,CAAAA,CAAI,MAAA,CAAQQ,CAAAA,CAAIC,CAAAA,CAAKD,CAAAA,EAAAA,CACrCe,CAAAA,CACEC,CAAAA,CAAS,GAAA,EAAO,OAAOxB,CAAAA,CAAIQ,CAAC,CAAA,GAAMtB,CAAAA,EAAUc,CAAAA,CAAIQ,CAAC,CAAA,CAAIA,CAAAA,CAAI,EAAA,CAAA,CAAM,GAAA,CAC/DR,CAAAA,CAAIQ,CAAC,CAAA,CACLiB,CAAAA,CAAQ,CACV,CAAA,CAAA,KAAA,GAEO5B,CAAAA,CAASG,CAAG,CAAA,CACrB,IAAKU,CAAAA,IAAOV,CAAAA,CACVuB,CAAAA,CAAYC,CAAAA,CAAS,GAAA,CAAMd,CAAAA,CAAM,GAAA,CAAKV,CAAAA,CAAIU,CAAG,CAAA,CAAGe,CAAAA,CAAQ,CAAC,CAAA,CAAA,KAG3DL,CAAAA,CAAII,CAAAA,CAAQxB,CAAG,CAAA,CAAA,KAAA,GAER,KAAA,CAAM,OAAA,CAAQA,CAAG,CAAA,CAC1B,IAAKQ,CAAAA,CAAI,CAAA,CAAGC,CAAAA,CAAMT,CAAAA,CAAI,MAAA,CAAQQ,CAAAA,CAAIC,CAAAA,CAAKD,CAAAA,EAAAA,CACrCY,CAAAA,CAAIpB,CAAAA,CAAIQ,CAAC,CAAA,CAAE,IAAA,CAAMR,CAAAA,CAAIQ,CAAC,CAAA,CAAE,KAAK,CAAA,CAAA,KAG/B,IAAKE,CAAAA,IAAOV,CAAAA,CACVuB,CAAAA,CAAYb,CAAAA,CAAKV,CAAAA,CAAIU,CAAG,CAAA,CAAGe,CAAAA,CAAQ,CAAC,CAAA,CAGxC,OAAOP,CACT,CAAA,CAMMD,CAAAA,CAJmBM,CAAAA,CAAY,EAAA,CAAIP,CAAM,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAIb,OAAA,CAAQ,SAAA,CAAW,IAAI,CAAA,CAEnE,OAAOL,EAAAA,CAAuBI,CAAAA,CAAKE,CAAkB,CACvD,CAWO,SAASS,EAAAA,CACdX,CAAAA,CACAY,CAAAA,CACQ,CACR,GAAI,CAACA,CAAAA,EAAiBZ,CAAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,GAAM,EAAA,CACzC,OAAOA,CAAAA,CAKT,IAAMC,CAAAA,CAASW,EAGf,OAAOZ,CAAAA,CAAI,OAAA,CAAQ,mBAAA,CAAqB,CAACa,CAAAA,CAAOlB,CAAAA,GAAQ,CAEtD,GAAI,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAKM,CAAAA,CAAQN,CAAG,CAAA,CAAG,CACrD,IAAMZ,CAAAA,CAAQkB,CAAAA,CAAON,CAAG,CAAA,CAGxB,GAA2BZ,CAAAA,EAAU,IAAA,CACnC,OAAO,kBAAA,CAAmB,MAAA,CAAOA,CAAK,CAAC,CAE3C,CAEA,OAAO8B,CACT,CAAC,CACH,CAUO,SAASC,EAAAA,CAAcd,CAAAA,CAAsB,CAClD,OAAOA,CAAAA,CAAI,QAAA,CAAS,KAAK,CAC3B,CAEO,IAAMe,CAAAA,CAAU,IAAM,IAAA,CAAK,GAAA,EAAI,CAEzBC,CAAAA,CAAO,IAAM,CAAC,CAAA,CAcpB,SAASC,EAAAA,CAAmBlC,CAAAA,CAAqB,CACtD,IAAM,CAAA,CAAI,OAAOA,CAAAA,CAEjB,OAA2BA,CAAAA,EAAU,IAAA,CAC5B,KAAA,CAGL,CAAA,GAAMX,CAAAA,EAAU,CAAA,GAAM,QAAA,EAAY,CAAA,GAAM,SAAA,EAIxC,KAAA,CAAM,OAAA,CAAQW,CAAK,CAAA,CACd,IAAA,CAIP,OAAO,UAAA,GAAeb,CAAAA,EACtB,OAAO,UAAA,CAAW,MAAA,GAAWA,CAAAA,EAC7B,UAAA,CAAW,MAAA,CAAO,QAAA,CAASa,CAAK,CAAA,EAK9BA,CAAAA,YAAiB,IAAA,EAAQH,EAAAA,CAAeG,CAAK,CAAA,CACxC,KAAA,CAGL,CAAA,EAAAD,CAAAA,CAASC,CAAK,CAAA,GACF,MAAA,CAAO,cAAA,CAAeA,CAAK,CAAA,GAG3B,MAAA,CAAO,SAAA,EAKjB,OAAOA,CAAAA,CAAM,MAAA,GAAWV,CAAAA,CAAAA,CAMhC,CAEA,eAAsB6C,CAAAA,CAAgBC,CAAAA,CAA8B,CAClE,OAAO,IAAI,OAAA,CAASC,CAAAA,EAClB,UAAA,CAAW,IACFA,CAAAA,CAAQ,IAAI,CAAA,CAClBD,CAAE,CACP,CACF,CAWO,SAASE,EAAAA,CAAYxC,CAAAA,CAAW6B,CAAAA,CAAQ,CAAA,CAAQ,CACrD,OAAIA,CAAAA,EAAS/B,EAAAA,CACJE,CAAAA,CAGLA,CAAAA,EAAQC,CAAAA,CAASD,CAAI,CAAA,EAAK,OAAOA,CAAAA,CAAK,IAAA,GAASX,CAAAA,CAC1CmD,EAAAA,CAAYxC,CAAAA,CAAK,IAAA,CAAM6B,CAAAA,CAAQ,CAAC,CAAA,CAGlC7B,CACT,CAYO,SAASyC,CAAAA,CACdC,CAAAA,CACe,CACf,GAAI,CAACA,CAAAA,CACH,OAAO,EAAC,CAGV,IAAMC,CAAAA,CAA+B,EAAC,CAItC,GAAID,CAAAA,YAAmB,OAAA,CACrBA,CAAAA,CAAQ,OAAA,CAAQ,CAACxC,CAAAA,CAAOY,CAAAA,GAAQ,CAC9B6B,CAAAA,CAAc7B,CAAAA,CAAI,WAAA,EAAa,CAAA,CAAIZ,EACrC,CAAC,CAAA,CAAA,KAAA,GACQD,CAAAA,CAASyC,CAAO,CAAA,CAEzB,IAAA,IAAW5B,CAAAA,IAAO4B,CAAAA,CACZ,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAKA,CAAAA,CAAS5B,CAAG,CAAA,GACnD6B,CAAAA,CAAc7B,CAAAA,CAAI,WAAA,EAAa,CAAA,CAAI4B,CAAAA,CAAQ5B,CAAG,CAAA,CAAA,CAKpD,OAAO6B,CACT,CAOO,SAASC,EAAAA,EAAqB,CAEnC,OACE,OAAO,MAAA,GAAWvD,CAAAA,EAAa,OAAO,MAAA,CAAO,gBAAA,GAAqBG,CAEtE,CAUO,SAASqD,EAAAA,CACdC,CAAAA,CACAC,CAAAA,CACsB,CACtB,GAAI,OAAO,YAAA,GAAiB1D,CAAAA,CAC1B,OAAO,IAAI,YAAA,CAAayD,CAAAA,CAASC,CAAI,CAAA,CAGvC,IAAMC,CAAAA,CAAQ,IAAI,KAAA,CAAMF,CAAO,CAAA,CAC/B,OAAAE,CAAAA,CAAM,IAAA,CAAOD,CAAAA,CAENC,CACT,CAMO,IAAMC,EAAAA,CAAmB,IAAe,CAC7C,IAAMC,CAAAA,CAAO,OAAO,SAAA,GAAc7D,CAAAA,EAAc,SAAA,CAAkB,UAAA,CAElE,OAAO6D,CAAAA,EAAQ,CAAC,SAAA,CAAW,IAAA,CAAM,IAAI,CAAA,CAAE,QAAA,CAASA,CAAAA,CAAK,aAAa,CACpE,ECpYA,eAAsBC,CAAAA,CAKpBC,CAAAA,CAA6BpD,CAAAA,CAAAA,GAAYqD,CAAAA,CAA2B,CACpE,GAAKD,CAAAA,CAAAA,CAIL,GAAI,OAAOA,CAAAA,GAAiB5D,CAAAA,CAAU,CACpC,IAAMU,CAAAA,CAAQ,MAAOkD,CAAAA,CACnBpD,CAAAA,CACA,GAAGqD,CACL,CAAA,CAEInD,CAAAA,EAASD,CAAAA,CAASD,CAAI,CAAA,EAAKC,CAAAA,CAASC,CAAK,CAAA,EAC3C,MAAA,CAAO,MAAA,CAAOF,CAAAA,CAAME,CAAK,EAE7B,CAAA,KAAA,GAAW,KAAA,CAAM,OAAA,CAAQkD,CAAY,CAAA,CACnC,IAAA,IAAWE,CAAAA,IAAeF,CAAAA,CAAc,CACtC,IAAMlD,CAAAA,CAAQ,MAAMoD,CAAAA,CAAYtD,CAAAA,CAAM,GAAGqD,CAAI,CAAA,CAEzCnD,CAAAA,EAASD,CAAAA,CAASD,CAAI,CAAA,EAAKC,CAAAA,CAASC,CAAK,CAAA,EAC3C,MAAA,CAAO,MAAA,CAAOF,CAAAA,CAAME,CAAK,EAE7B,CAAA,CAEJ,CCjCO,IAAMqD,EAAAA,CAAN,cAKG,KAAM,CAMd,WAAA,CACET,CAAAA,CACOU,CAAAA,CAMAC,CAAAA,CAMP,CACA,KAAA,CAAMX,CAAO,CAAA,CAbN,IAAA,CAAA,OAAA,CAAAU,CAAAA,CAMA,IAAA,CAAA,QAAA,CAAAC,CAAAA,CASP,IAAA,CAAK,IAAA,CAAO,YAAA,CACZ,IAAA,CAAK,MAAA,CAASA,CAAAA,CAAWA,CAAAA,CAAS,MAAA,CAAS,CAAA,CAC3C,IAAA,CAAK,UAAA,CAAaA,CAAAA,CAAWA,CAAAA,CAAS,UAAA,CAAa,EAAA,CACnD,IAAA,CAAK,MAAA,CAASD,CAAAA,CACd,IAAA,CAAK,WAAA,CAAc,MACrB,CA3BA,MAAA,CACA,UAAA,CACA,MAAA,CACA,WAyBF,CAAA,CCpCO,IAAME,EAAAA,CAAN,cAKGH,EAA+D,CACvE,WAAA,CACET,CAAAA,CACAU,CAAAA,CACAC,CAAAA,CAMA,CACA,KAAA,CAAMX,CAAAA,CAASU,CAAAA,CAASC,CAAQ,CAAA,CAEhC,IAAA,CAAK,IAAA,CAAO,gBACd,CACF,CAAA,CCHA,IAAME,EAAAA,CAAa,GAAA,CACbC,CAAAA,CAAS,GAAA,CACTC,EAAAA,CAAeF,EAAAA,CAAaC,CAAAA,CAC5BE,EAAAA,CAAyB,KAAA,CAAMH,EAAU,CAAA,CAC5C,IAAA,CAAK,CAAC,CAAA,CACN,GAAA,CAAI,IAAM,EAAE,CAAA,CAETI,CAAAA,CAAS,IAAI,GAAA,CACfC,EAAAA,CAAW,CAAA,CACXC,CAAAA,CAA+B,IAAA,CAE7BC,EAAAA,CAAiB,CAAC,CAACpD,CAAAA,CAAKqD,CAAQ,CAAA,GAAyB,CAC7DJ,CAAAA,CAAO,MAAA,CAAOjD,CAAG,CAAA,CAEjB,GAAI,CACF,IAAMsD,CAAAA,CAASD,CAAAA,EAAS,CACpBC,CAAAA,EAAUA,CAAAA,YAAkB,OAAA,EAE9BA,CAAAA,CAAO,KAAA,CAAMjC,CAAI,EAErB,CAAA,KAAQ,CAER,CACF,CAAA,CAEakC,CAAAA,CAAa,CACxBvD,CAAAA,CACAwD,CAAAA,CACAhC,CAAAA,GACS,CAIT,GAHAiC,CAAAA,CAAczD,CAAG,CAAA,CAGbwB,CAAAA,CAAKsB,CAAAA,EAAUtB,CAAAA,CAAKuB,EAAAA,EAAgBvB,CAAAA,CAAKsB,CAAAA,GAAW,CAAA,CAAG,CACzDG,CAAAA,CAAO,GAAA,CAAIjD,CAAAA,CAAK,CAAC,UAAA,CAAWoD,EAAAA,CAAe,IAAA,CAAK,IAAA,CAAM,CAACpD,CAAAA,CAAKwD,CAAE,CAAC,CAAA,CAAGhC,CAAE,CAAC,CAAC,CAAA,CAEtE,MACF,CAGA,IAAMkC,CAAAA,CAAUlC,CAAAA,CAAKsB,CAAAA,CACfa,CAAAA,CAAAA,CAAQT,EAAAA,CAAWQ,CAAAA,EAAWb,EAAAA,CAEpCG,EAAAA,CAAMW,CAAI,CAAA,CAAE,IAAA,CAAK,CAAC3D,CAAAA,CAAKwD,CAAE,CAAC,CAAA,CAC1BP,CAAAA,CAAO,GAAA,CAAIjD,CAAAA,CAAK2D,CAAI,EAEfR,CAAAA,GACHA,CAAAA,CAAQ,WAAA,CAAY,IAAM,CACxBD,EAAAA,CAAAA,CAAYA,EAAAA,CAAW,CAAA,EAAKL,EAAAA,CAC5B,IAAMc,CAAAA,CAAOX,EAAAA,CAAME,EAAQ,CAAA,CAI3B,IAAA,IAASpD,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAI6D,CAAAA,CAAK,MAAA,CAAQ7D,CAAAA,EAAAA,CAC/BsD,EAAAA,CAAeO,CAAAA,CAAK7D,CAAC,CAAC,CAAA,CAGxB6D,CAAAA,CAAK,MAAA,CAAS,CAAA,CAEV,CAACV,CAAAA,CAAO,IAAA,EAAQE,CAAAA,GAClB,aAAA,CAAcA,CAAK,CAAA,CACnBA,CAAAA,CAAQ,IAAA,EAEZ,CAAA,CAAGL,CAAM,CAAA,EAEb,CAAA,CAEaW,CAAAA,CAAiBzD,CAAAA,EAAsB,CAClD,IAAM4D,CAAAA,CAAgBX,CAAAA,CAAO,GAAA,CAAIjD,CAAG,CAAA,CAEpC,GAAI4D,CAAAA,GAAkB,MAAA,CAAW,CAE/B,GAAI,KAAA,CAAM,OAAA,CAAQA,CAAa,CAAA,CAC7B,YAAA,CAAaA,CAAAA,CAAc,CAAC,CAAC,CAAA,CAAA,KACxB,CACL,IAAMC,CAAAA,CAAUb,EAAAA,CAAMY,CAAa,CAAA,CAC7BE,CAAAA,CAAMD,CAAAA,CAAQ,SAAA,CAAU,CAAC,CAAClD,CAAC,CAAA,GAAMA,CAAAA,GAAMX,CAAG,CAAA,CAE5C8D,CAAAA,GAAQ,EAAA,EACVD,CAAAA,CAAQ,MAAA,CAAOC,CAAAA,CAAK,CAAC,EAEzB,CAEAb,CAAAA,CAAO,MAAA,CAAOjD,CAAG,CAAA,CAEb,CAACiD,CAAAA,CAAO,IAAA,EAAQE,CAAAA,GAClB,aAAA,CAAcA,CAAK,CAAA,CACnBA,CAAAA,CAAQ,IAAA,EAEZ,CACF,ECrFA,IAAMY,CAAAA,CAAsC,IAAI,GAAA,CAazC,SAASC,EAAAA,CACdhE,CAAAA,CACAK,CAAAA,CACA4D,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACiB,CACjB,GAAI,CAACpE,CAAAA,CACH,OAAO,IAAI,eAAA,CAGb,IAAMqE,CAAAA,CAAMjD,CAAAA,EAAQ,CACdkD,CAAAA,CAAOP,EAAS,GAAA,CAAI/D,CAAG,CAAA,CACzBuE,CAAAA,CAAuC,IAAA,CAG3C,GAAID,CAAAA,CAAM,CACR,IAAME,CAAAA,CAAiBF,CAAAA,CAAK,CAAC,CAAA,CACvBG,CAAAA,CAAoBH,CAAAA,CAAK,CAAC,CAAA,CAGhC,GACE,CAACG,CAAAA,EACDJ,CAAAA,CAAMC,CAAAA,CAAK,CAAC,CAAA,CAAIJ,CAAAA,EAChB,CAACM,CAAAA,CAAe,MAAA,CAAO,OAAA,CAEvB,OAAOA,CAAAA,CAKLC,CAAAA,EACFD,CAAAA,CAAe,KAAA,CACbzC,EAAAA,CAAiB,4BAAA,CAA8BpD,EAAW,CAC5D,CAAA,CAGF8E,CAAAA,CAAczD,CAAG,CAAA,CACjBuE,CAAAA,CAAcD,CAAAA,CAAK,CAAC,EACtB,CAEA,IAAMI,CAAAA,CAAa,IAAI,eAAA,CAEvB,OAAAX,CAAAA,CAAS,GAAA,CAAI/D,CAAAA,CAAK,CAChB0E,CAAAA,CACAN,CAAAA,CACAC,CAAAA,CACAF,CAAAA,CACAI,CACF,CAAC,CAAA,CAEGH,CAAAA,EACFb,CAAAA,CACEvD,CAAAA,CACA,IAAM,CACJ2E,EAAAA,CACE3E,CAAAA,CACA+B,EAAAA,CAAiB1B,CAAAA,CAAM,yBAAA,CAA2BzB,EAAa,CACjE,EACF,CAAA,CACAqF,CACF,CAAA,CAGKS,CACT,CASA,eAAsBC,EAAAA,CACpB3E,CAAAA,CACAkC,CAAAA,CAA8C,IAAA,CAC/B,CAEf,GAAIlC,CAAAA,CAAK,CACP,IAAMsE,CAAAA,CAAOP,CAAAA,CAAS,GAAA,CAAI/D,CAAG,CAAA,CAEzBsE,CAAAA,GAEEpC,CAAAA,EACiBoC,CAAAA,CAAK,CAAC,CAAA,CACd,KAAA,CAAMpC,CAAK,CAAA,CAGxB0C,EAAAA,CAAe5E,CAAG,CAAA,EAEtB,CACF,CAOO,SAAS4E,EAAAA,CAAe5E,CAAAA,CAA0B,CACvDyD,CAAAA,CAAczD,CAAI,CAAA,CAClB+D,CAAAA,CAAS,MAAA,CAAO/D,CAAI,EACtB,CAsBO,SAAS6E,EAAAA,CACd7E,CAAAA,CACA8E,CAAAA,CACM,CACN,IAAMR,CAAAA,CAAOP,CAAAA,CAAS,GAAA,CAAI/D,CAAG,CAAA,CACzBsE,CAAAA,GAEFA,CAAAA,CAAK,CAAC,CAAA,CAAIQ,CAAAA,EAEd,CASO,SAASC,EAAAA,CACd/E,CAAAA,CACAkE,CAAAA,CACmB,CACnB,GAAI,CAAClE,CAAAA,CACH,OAAO,IAAA,CAGT,IAAMgF,CAAAA,CAAUjB,CAAAA,CAAS,GAAA,CAAI/D,CAAG,CAAA,CAEhC,OACEgF,CAAAA,EAEAA,CAAAA,CAAQ,CAAC,CAAA,EAET,CAACA,CAAAA,CAAQ,CAAC,CAAA,EAEV5D,CAAAA,EAAQ,CAAI4D,CAAAA,CAAQ,CAAC,CAAA,CAAId,CAAAA,EAEzB,CAACc,CAAAA,CAAQ,CAAC,CAAA,CAAE,MAAA,CAAO,OAAA,CAEZA,CAAAA,CAAQ,CAAC,CAAA,CAGX,IACT,CC3MO,SAASC,CAAAA,CAAKC,CAAAA,CAAqB,CACxC,IAAID,CAAAA,CAAO,CAAA,CAEX,IAAA,IAASnF,CAAAA,CAAI,CAAA,CAAGC,CAAAA,CAAMmF,CAAAA,CAAI,MAAA,CAAQpF,CAAAA,CAAIC,CAAAA,CAAKD,CAAAA,EAAAA,CAAK,CAC9C,IAAMqF,CAAAA,CAAOD,CAAAA,CAAI,UAAA,CAAWpF,CAAC,CAAA,CAC7BmF,CAAAA,CAAQA,CAAAA,CAAO,EAAA,CAAmBE,CAAAA,CAAQ,EAC5C,CAEA,OAAO,MAAA,CAAOF,CAAI,CACpB,CCmBA,IAAMG,EAAAA,CAAc,GAAA,CAAS,GAAA,CACvBC,CAAAA,CAAe,IAAI,GAAA,CASnBC,CAAAA,CAAgB,IAAI,GAAA,CAKpBC,EAAAA,CAAuB,IAAI,GAAA,CAS1B,SAASC,EAAAA,CACdC,CAAAA,CACAC,CAAAA,CACM,CACNH,EAAAA,CAAqB,GAAA,CAAIE,CAAAA,CAAMC,CAAQ,CAAA,CAGnCJ,CAAAA,CAAc,GAAA,CAAIG,CAAI,CAAA,GACxBE,EAAAA,CAAmBF,CAAI,CAAA,CACvBG,EAAAA,CAAgBH,CAAI,CAAA,EAExB,CAUO,SAASI,EAAAA,CACdJ,CAAAA,CACAK,CAAAA,CAA+B,IAAA,CAC/B,CACA,IAAMC,CAAAA,CAAYN,IAAS,OAAA,CAAU,CAAA,CAAI,CAAA,CACnCpB,CAAAA,CAAMjD,CAAAA,EAAQ,CAEpBiE,CAAAA,CAAa,OAAA,CAASW,CAAAA,EAAU,CAC9B,GAAI,CAACA,CAAAA,CAAMD,CAAS,CAAA,CAClB,OAGFC,CAAAA,CAAM,CAAC,CAAA,CAAI3B,CAAAA,CAGX,IAAM4B,CAAAA,CAAcH,CAAAA,CAAsBE,CAAAA,CAAM,CAAC,CAAA,CAAIA,CAAAA,CAAM,CAAC,CAAA,CAExDC,CAAAA,EACF,OAAA,CAAQ,OAAA,CAAQA,CAAAA,CAAYH,CAAmB,CAAC,CAAA,CAAE,KAAA,CAAMzE,CAAI,EAEhE,CAAC,EACH,CAUA,eAAsB6E,EAAAA,CACpBlG,CAAAA,CACA8F,CAAAA,CAA+B,KAAA,CACI,CAEnC,GAAI,CAAC9F,CAAAA,CACH,OAAO,IAAA,CAGT,IAAMgG,CAAAA,CAAQX,CAAAA,CAAa,GAAA,CAAIrF,CAAG,CAAA,CAElC,GAAIgG,CAAAA,CAAO,CAETA,CAAAA,CAAM,CAAC,CAAA,CAAI5E,CAAAA,EAAQ,CAEnB,IAAM6E,CAAAA,CAAcH,CAAAA,CAAsBE,CAAAA,CAAM,CAAC,CAAA,CAAIA,CAAAA,CAAM,CAAC,CAAA,CAG5D,GAAIC,CAAAA,CACF,OAAO,MAAMA,CAAAA,CAAYH,CAAmB,CAEhD,CAGA,OAAO,IACT,CAOO,SAASK,EAAAA,CAAmBV,CAAAA,CAAiB,CAClDE,EAAAA,CAAmBF,CAAI,CAAA,CAEvB,IAAMM,CAAAA,CAAYN,CAAAA,GAAS,OAAA,CAAU,CAAA,CAAI,CAAA,CAGzCJ,CAAAA,CAAa,OAAA,CAAQ,CAACW,CAAAA,CAAOhG,CAAAA,GAAQ,CAC/BgG,CAAAA,CAAMD,CAAS,CAAA,EACjBK,EAAAA,CAAkBpG,CAAG,EAEzB,CAAC,EACH,CASA,SAAS4F,EAAAA,CAAgBS,CAAAA,CAAkB,CACzC,GAAIf,CAAAA,CAAc,GAAA,CAAIe,CAAK,CAAA,CACzB,OAGF,IAAMC,CAAAA,CAAUT,EAAAA,CAAc,KAAK,IAAA,CAAMQ,CAAAA,CAAO,IAAI,CAAA,CAG9CE,CAAAA,CAAiBhB,EAAAA,CAAqB,GAAA,CAAIc,CAAK,CAAA,CAErD,GAAIE,CAAAA,CAAgB,CAClB,IAAMC,CAAAA,CAAUD,CAAAA,CAAeD,CAAO,CAAA,CAEtChB,CAAAA,CAAc,GAAA,CAAIe,CAAAA,CAAOG,CAAO,CAAA,CAEhC,MACF,CAGI1E,EAAAA,EAAU,GACZ,MAAA,CAAO,gBAAA,CAAiBuE,CAAAA,CAAOC,CAAO,CAAA,CAEtChB,CAAAA,CAAc,GAAA,CAAIe,CAAAA,CAAO,IAAM,MAAA,CAAO,mBAAA,CAAoBA,CAAAA,CAAOC,CAAO,CAAC,CAAA,EAE7E,CAOA,SAASX,EAAAA,CAAmBU,CAAAA,CAAkB,CAC5C,IAAMG,CAAAA,CAAUlB,CAAAA,CAAc,GAAA,CAAIe,CAAK,CAAA,CAEnCG,CAAAA,GACFA,CAAAA,EAAQ,CACRlB,CAAAA,CAAc,MAAA,CAAOe,CAAK,CAAA,EAE9B,CAaO,SAASI,EAAAA,CACdzG,CAAAA,CACA0G,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACA,CACA,IAAMC,CAAAA,CAAW3B,CAAAA,CAAa,GAAA,CAAIrF,CAAG,CAAA,CAEjCgH,CAAAA,EAEFA,CAAAA,CAAS,CAAC,CAAA,CAAIN,CAAAA,CACdM,CAAAA,CAAS,CAAC,CAAA,CAAI5F,CAAAA,EAAQ,CACtB4F,CAAAA,CAAS,CAAC,CAAA,CAAW5B,EAAAA,CACrB4B,CAAAA,CAAS,CAAC,CAAA,CAAIJ,CAAAA,CACdI,CAAAA,CAAS,CAAC,CAAA,CAAIH,CAAAA,CACdG,CAAAA,CAAS,CAAC,CAAA,CAAIF,CAAAA,CACdE,CAAAA,CAAS,CAAC,CAAA,CAAID,CAAAA,EAEd1B,CAAAA,CAAa,GAAA,CAAIrF,CAAAA,CAAK,CACpB0G,CAAAA,CACAtF,CAAAA,EAAQ,CACDgE,EAAAA,CACPwB,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CACF,CAAC,CAAA,CAGCD,CAAAA,EACFlB,EAAAA,CAAgB,OAAO,CAAA,CAGrBmB,CAAAA,EACFnB,EAAAA,CAAgB,QAAQ,CAAA,CAGtBgB,CAAAA,EACFrD,CAAAA,CAAW,IAAA,CAAOvD,CAAAA,CAAKkG,EAAAA,CAAW,IAAA,CAAK,IAAA,CAAMlG,CAAAA,CAAK,IAAI,CAAA,CAAG4G,CAAAA,CAAY,GAAI,EAE7E,CAEO,SAASR,EAAAA,CAAkBpG,CAAAA,CAAa,CAC7CqF,CAAAA,CAAa,MAAA,CAAOrF,CAAG,CAAA,CAGvByD,CAAAA,CAAc,IAAA,CAAOzD,CAAG,EAC1B,CChPA,IAAMiH,CAAAA,CAAY,IAAI,GAAA,CAEtB,SAASC,EAAAA,CAAkBlH,CAAAA,CAAa,CACtC,IAAImH,CAAAA,CAAMF,CAAAA,CAAU,GAAA,CAAIjH,CAAG,CAAA,CAE3B,OAAKmH,CAAAA,GACHA,CAAAA,CAAM,IAAI,GAAA,CACVF,CAAAA,CAAU,GAAA,CAAIjH,CAAAA,CAAKmH,CAAG,CAAA,CAAA,CAGjBA,CACT,CAGO,SAASC,EAAAA,CAAqBpH,CAAAA,CAAaqH,CAAAA,CAAuB,CACvEH,EAAAA,CAAkBlH,CAAG,CAAA,CAAE,GAAA,CAAIqH,CAAE,EAC/B,CAEO,SAASC,EAAAA,CAAkBtH,CAAAA,CAAaqH,CAAAA,CAAiB,CAC9D,IAAMF,CAAAA,CAAMF,CAAAA,CAAU,GAAA,CAAIjH,CAAG,CAAA,CAEzBmH,CAAAA,GACFA,CAAAA,CAAI,MAAA,CAAOE,CAAE,CAAA,CAGTF,CAAAA,CAAI,IAAA,GAAS,CAAA,EACfF,CAAAA,CAAU,MAAA,CAAOjH,CAAG,CAAA,EAG1B,CAEO,SAASuH,CAAAA,CAAqBvH,CAAAA,CAAa2C,CAAAA,CAAa,CAC7D,IAAM6E,CAAAA,CAAMP,CAAAA,CAAU,GAAA,CAAIjH,CAAG,CAAA,CAE7B,GAAIwH,CAAAA,CACF,GAAIA,CAAAA,CAAI,IAAA,GAAS,CAAA,CAAG,CAElB,IAAMH,CAAAA,CAAKG,CAAAA,CAAI,MAAA,EAAO,CAAE,IAAA,EAAK,CAAE,KAAA,CAC/BH,CAAAA,CAAI1E,CAAQ,EACd,CAAA,KACE6E,CAAAA,CAAI,OAAA,CAASH,CAAAA,EAAOA,CAAAA,CAAG1E,CAAQ,CAAC,EAGtC,CAEO,SAAS8E,EAAAA,CAAazH,CAAAA,CAAoBqH,CAAAA,CAA2B,CAC1E,OAAKrH,CAAAA,EAKLoH,EAAAA,CAAepH,CAAAA,CAAKqH,CAAE,CAAA,CAGf,IAAM,CACXC,EAAAA,CAAetH,CAAAA,CAAKqH,CAAE,EACxB,CAAA,EARShG,CASX,CCxDA,IAAMqG,EAAAA,CAAAA,CAAoBvF,EAAAA,EAAiB,CAAI,EAAA,CAAK,EAAA,EAAM,GAAA,CAE7CwF,CAAAA,CAA+B,CAC1C,QAAA,CAAU5I,EAAAA,CACV,OAAA,CAAS2I,EAAAA,CACT,OAAA,CAAS,CACP,MAAA,CAAQtJ,CAAAA,CAAmB,mBAAA,CAC3B,iBAAA,CAAmB,mBACrB,CAAA,CACA,KAAA,CAAO,CACL,KAAA,CAAOsJ,EAAAA,CAAmB,EAAA,CAC1B,QAAA,CAAUA,EAAAA,CACV,YAAA,CAAc,IAAA,CACd,OAAA,CAAS,GAAA,CAGT,OAAA,CAAS,CACP,GAAA,CACA,GAAA,CACA,GAAA,CACA,GAAA,CACA,GAAA,CACA,GAAA,CACA,GAAA,CACA,GACF,CACF,CACF,CAAA,CAQO,SAASE,EAAAA,CACdC,CAAAA,CACwB,CACxB,IAAMC,CAAAA,CAAYzI,CAAAA,CAAewI,CAAY,CAAA,CAE7C,OAAOE,CAAAA,CAAa,EAAC,CAAGD,CAAAA,CAAWH,CAAa,CAClD,CAOO,SAASK,EAAAA,EAAkC,CAChD,OAAO,CAAE,GAAGL,CAAc,CAC5B,CASO,SAASM,EAAAA,CACd5H,CAAAA,CACA6H,CAAAA,CAMmE,CACnE,GAAI,CAACA,CAAAA,CACH,OAAOC,EAAAA,CAAmB9H,CAAAA,CAAK2H,EAAAA,EAAkB,CAAA,CAGnD,IAAMF,CAAAA,CAAYzI,CAAAA,CAAe6I,CAAS,CAAA,CACpCE,CAAAA,CAASL,CAAAA,CAAaJ,CAAAA,CAAeG,CAAS,CAAA,CAEpD,OAAOK,EAAAA,CAAmB9H,CAAAA,CAAK+H,CAAM,CACvC,CASO,SAASD,EAAAA,CACd9H,CAAAA,CACAgI,CAAAA,CACe,CACf,IAAIC,CAAAA,CAASD,CAAAA,CAAc,OAC3BC,CAAAA,CAASA,CAAAA,CAAUA,CAAAA,CAAO,WAAA,EAAY,CAAezJ,CAAAA,CAErD,IAAI0J,CAAAA,CAGAD,CAAAA,GAAWzJ,CAAAA,EAAOyJ,CAAAA,GAAWxJ,EAAAA,GAC/ByJ,CAAAA,CAAOF,CAAAA,CAAc,IAAA,EAAQA,CAAAA,CAAc,IAAA,CAGvCE,CAAAA,EAAQ,OAAOA,CAAAA,GAAS9J,CAAAA,EAAU6C,EAAAA,CAAmBiH,CAAI,CAAA,GAC3DA,CAAAA,CAAO,IAAA,CAAK,SAAA,CAAUA,CAAI,CAAA,CAAA,CAAA,CAI9BC,EAAAA,CAAuBH,CAAAA,CAAc,OAAA,CAASE,CAAI,CAAA,CAGlD,IAAME,CAAAA,CAAcJ,CAAAA,CAAc,eAAA,CAC9B,SAAA,CACAA,CAAAA,CAAc,WAAA,CAGZK,CAAAA,CAAa1H,EAAAA,CAAqBX,CAAAA,CAAKgI,CAAAA,CAAc,aAAa,CAAA,CAClEM,CAAAA,CAAUvI,EAAAA,CAAkBsI,CAAAA,CAAYL,CAAAA,CAAc,MAAM,CAAA,CAE5DO,CAAAA,CADYzH,EAAAA,CAAcd,CAAG,CAAA,CAE/B,EAAA,CACAgI,CAAAA,CAAc,OAAA,EAAWA,CAAAA,CAAc,MAAA,EAAU,EAAA,CAErD,OAAAA,CAAAA,CAAc,GAAA,CAAMO,CAAAA,CAAUD,CAAAA,CAC9BN,CAAAA,CAAc,MAAA,CAASC,CAAAA,CACvBD,CAAAA,CAAc,WAAA,CAAcI,CAAAA,CAC5BJ,CAAAA,CAAc,IAAA,CAAOE,CAAAA,CAEdF,CACT,CAWA,SAASG,EAAAA,CACP5G,CAAAA,CACA2G,CAAAA,CACM,CAON,GALI,CAAC3G,CAAAA,EAAW,CAAC2G,CAAAA,EAMfA,CAAAA,YAAgB,QAAA,EACf,OAAO,IAAA,GAAShK,CAAAA,EAAagK,CAAAA,YAAgB,IAAA,EAC7C,OAAO,IAAA,GAAShK,CAAAA,EAAagK,CAAAA,YAAgB,IAAA,EAC7C,OAAO,cAAA,GAAmBhK,CAAAA,EAAagK,CAAAA,YAAgB,cAAA,CAExD,OAGF,IAAIM,CAAAA,CAEJ,GAAI5J,EAAAA,CAAesJ,CAAI,CAAA,CACrBM,CAAAA,CAAmB1K,CAAAA,CAA2B,uBAAA,CAAA,KAAA,GACrCoK,CAAAA,YAAgB,WAAA,EAAe,WAAA,CAAY,MAAA,CAAOA,CAAI,CAAA,CAC/DM,CAAAA,CAAmB1K,CAAAA,CAA2B,cAAA,CAAA,KAAA,GACrCmD,EAAAA,CAAmBiH,CAAI,CAAA,CAChCM,EAAmBzK,CAAAA,CAAmB,GAAA,CAAMC,EAAAA,CAAAA,KAG5C,OAGEuD,CAAAA,YAAmB,OAAA,CAChBA,CAAAA,CAAQ,GAAA,CAAItD,CAAY,CAAA,EAC3BsD,CAAAA,CAAQ,GAAA,CAAItD,CAAAA,CAAcuK,CAAgB,CAAA,CAG5C1J,CAAAA,CAASyC,CAAO,CAAA,EAChB,CAAC,KAAA,CAAM,OAAA,CAAQA,CAAO,CAAA,EACtB,CAACA,CAAAA,CAAQtD,CAAY,CAAA,GAErBsD,CAAAA,CAAQtD,CAAY,CAAA,CAAIuK,CAAAA,EAE5B,CAmBO,SAASd,CAAAA,CACde,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CAA8B,EAAC,CAChB,CACf,OAAA,MAAA,CAAO,MAAA,CAAOA,CAAAA,CAAcF,CAAAA,CAAYC,CAAc,CAAA,CAGtDE,EAAAA,CAAY,OAAA,CAASH,CAAAA,CAAYC,CAAAA,CAAgBC,CAAY,CAAA,CAC7DC,EAAAA,CAAY,SAAA,CAAWH,CAAAA,CAAYC,CAAAA,CAAgBC,CAAY,CAAA,CAG/DE,EAAAA,CAAkB,WAAA,CAAaJ,CAAAA,CAAYC,CAAAA,CAAgBC,CAAY,CAAA,CACvEE,EAAAA,CAAkB,YAAA,CAAcJ,CAAAA,CAAYC,CAAAA,CAAgBC,CAAY,CAAA,CACxEE,EAAAA,CAAkB,SAAA,CAAWJ,CAAAA,CAAYC,CAAAA,CAAgBC,CAAY,CAAA,CAE9DA,CACT,CAKA,SAASE,EAAAA,CAGPC,CAAAA,CACAL,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACM,CACN,IAAMI,CAAAA,CAAkBN,CAAAA,CAAWK,CAAQ,CAAA,CACrCE,CAAAA,CAAiBN,CAAAA,CAAeI,CAAQ,CAAA,CAE9C,GAAI,CAACC,CAAAA,EAAmB,CAACC,CAAAA,CACvB,OAGF,GAAI,CAACD,CAAAA,CAAiB,CACpBJ,CAAAA,CAAaG,CAAQ,CAAA,CAAIE,CAAAA,CACzB,MACF,CAEA,GAAI,CAACA,CAAAA,CAAgB,CACnBL,CAAAA,CAAaG,CAAQ,CAAA,CAAIC,CAAAA,CACzB,MACF,CAEA,IAAME,CAAAA,CAAU,KAAA,CAAM,OAAA,CAAQF,CAAe,CAAA,CACzCA,CAAAA,CACA,CAACA,CAAe,CAAA,CACdG,CAAAA,CAAS,KAAA,CAAM,OAAA,CAAQF,CAAc,CAAA,CACvCA,CAAAA,CACA,CAACA,CAAc,CAAA,CAGnBL,CAAAA,CAAaG,CAAQ,CAAA,CACnBA,CAAAA,GAAa,YAAA,CAAeI,CAAAA,CAAO,MAAA,CAAOD,CAAO,CAAA,CAAIA,CAAAA,CAAQ,MAAA,CAAOC,CAAM,EAC9E,CAUO,SAASN,EAAAA,CACdE,CAAAA,CACAL,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACM,CACN,GAAID,CAAAA,CAAeI,CAAQ,CAAA,CAAG,CAC5B,IAAMK,CAAAA,CAAOV,CAAAA,CAAWK,CAAQ,CAAA,CAC1BM,CAAAA,CAAWV,CAAAA,CAAeI,CAAQ,CAAA,CAGxC,GACEA,CAAAA,GAAa,SAAA,GACXK,CAAAA,YAA4D,OAAA,EAC3DC,CAAAA,YACC,OAAA,CAAA,CACJ,CACA,IAAMC,CAAAA,CAAiB/H,CAAAA,CAAe6H,CAAI,CAAA,CACpCG,CAAAA,CAAqBhI,CAAAA,CAAe8H,CAAQ,CAAA,CAClDT,CAAAA,CAAaG,CAAQ,CAAA,CAAI,CACvB,GAAGO,CAAAA,CACH,GAAGC,CACL,EACF,CAAA,KACEX,CAAAA,CAAaG,CAAQ,CAAA,CAAI,CACvB,GAAGK,CAAAA,CACH,GAAGC,CACL,EAEJ,CACF,CC7SA,IAAMG,EAAAA,CAAS,IAAI,GAAA,CACbC,CAAAA,CAAY,GAAA,CACZC,EAAAA,CAAqB,EAAA,CACrBC,EAAAA,CAA6B,sBAAA,CAC7BC,EAAAA,CAA2B,qBAAA,CAM3BC,EAAAA,CAA6B,IAAI,GAAA,CAAI,CAEzC,QAAA,CACA,iBAAA,CACA,iBAAA,CAGA,eAAA,CAGA,cAAA,CAGA,SAAA,CACA,QAAA,CACA,YAAA,CAGA,QAAA,CAGA,WAAA,CACA,kBAAA,CACA,aAAA,CACA,aAAA,CACA,WAAA,CAEA,eAAA,CACA,gBAAA,CACA,aAAA,CACA,YAAA,CAEA,cAAA,CACA,UACF,CAAC,CAAA,CA0BM,SAASC,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CAAgB,IAAA,CACR,CAGR,IAAMpK,CAAAA,CAAMmK,CAAAA,CAAO,QAAA,CAEnB,GAAInK,CAAAA,EAAOoK,CAAAA,CACT,OAAO,OAAOpK,CAAAA,GAAQvB,CAAAA,CACjBuB,CAAAA,CACAA,CAAAA,CAAyBmK,CAAM,CAAA,CAGtC,GAAM,CACJ,GAAA,CAAA9J,CAAAA,CAAM,EAAA,CACN,MAAA,CAAAiI,CAAAA,CAASzJ,CAAAA,CACT,OAAA,CAAA+C,CAAAA,CAAU,IAAA,CACV,IAAA,CAAA2G,CAAAA,CAAO,IAAA,CACP,WAAA,CAAAE,CAAAA,CAAc,aAChB,CAAA,CAAI0B,CAAAA,CAIAE,CAAAA,CAAgB,EAAA,CACpB,GAAIzI,CAAAA,CAAS,CACX,IAAItC,CAAAA,CAEAsC,CAAAA,YAAmB,OAAA,CACrBtC,CAAAA,CAAMqC,CAAAA,CAAeC,CAAO,CAAA,CAE5BtC,CAAAA,CAAMsC,CAAAA,CAKR,IAAMhC,CAAAA,CAAO,MAAA,CAAO,IAAA,CAAKN,CAAG,CAAA,CACtBS,CAAAA,CAAMH,CAAAA,CAAK,MAAA,CAGbG,CAAAA,CAAM,CAAA,EACRH,CAAAA,CAAK,IAAA,EAAK,CAGZ,IAAIsF,CAAAA,CAAM,EAAA,CACV,IAAA,IAASpF,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIC,CAAAA,CAAK,EAAED,CAAAA,CACrBmK,EAAAA,CAA2B,GAAA,CAAIrK,CAAAA,CAAKE,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,GACtDoF,CAAAA,EAAOtF,CAAAA,CAAKE,CAAC,CAAA,CAAI,GAAA,CAAMR,CAAAA,CAAIM,CAAAA,CAAKE,CAAC,CAAC,CAAA,CAAI,GAAA,CAAA,CAI1CuK,CAAAA,CAAgBpF,CAAAA,CAAKC,CAAG,EAC1B,CAGA,GAAIoD,CAAAA,GAAWzJ,CAAAA,CAAK,CAClB,IAAMyL,CAAAA,CACJhC,CAAAA,CACAuB,CAAAA,CACAxJ,CAAAA,CACAwJ,CAAAA,CACApB,CAAAA,CACAoB,CAAAA,CACAQ,CAAAA,CAEF,OAAOL,EAAAA,CAAyB,IAAA,CAAKM,CAAQ,CAAA,CACzCA,CAAAA,CAAS,OAAA,CAAQP,EAAAA,CAA4B,EAAE,CAAA,CAC/CO,CACN,CAEA,IAAIC,CAAAA,CAAa,EAAA,CACjB,GAAIhC,CAAAA,CACF,GAAI,OAAOA,IAAS9J,CAAAA,CAClB8L,CAAAA,CAAahC,CAAAA,CAAK,MAAA,CAASuB,EAAAA,CAAqBvB,CAAAA,CAAOtD,CAAAA,CAAKsD,CAAI,CAAA,CAAA,KAAA,GACvDA,CAAAA,YAAgB,QAAA,CACzBA,CAAAA,CAAK,OAAA,CAAQ,CAACnJ,CAAAA,CAAOY,CAAAA,GAAQ,CAE3BuK,CAAAA,EAAcvK,CAAAA,CAAM,GAAA,CAAMZ,CAAAA,CAAQ,IACpC,CAAC,CAAA,CAEGmL,CAAAA,CAAW,MAAA,CAAST,EAAAA,GACtBS,CAAAA,CAAatF,CAAAA,CAAKsF,CAAU,CAAA,CAAA,CAAA,KAAA,GAG7B,OAAO,IAAA,GAAShM,CAAAA,EAAagK,CAAAA,YAAgB,IAAA,EAC7C,OAAO,IAAA,GAAShK,CAAAA,EAAagK,CAAAA,YAAgB,IAAA,CAE9CgC,CAAAA,CAAa,IAAA,CAAOhC,CAAAA,CAAK,IAAA,CAAOA,CAAAA,CAAK,IAAA,CAAA,KAAA,GAC5BA,CAAAA,YAAgB,WAAA,EAAe,WAAA,CAAY,MAAA,CAAOA,CAAI,CAAA,CAC/DgC,CAAAA,CAAa,IAAA,CAAOhC,CAAAA,CAAK,UAAA,CAAA,KACpB,CACL,IAAMiC,CAAAA,CAAIrL,CAAAA,CAASoJ,CAAI,CAAA,CACnB,IAAA,CAAK,SAAA,CAAU5I,EAAAA,CAAW4I,CAAI,CAAC,CAAA,CAC/B,MAAA,CAAOA,CAAI,CAAA,CAEfgC,CAAAA,CAAaC,CAAAA,CAAE,MAAA,CAASV,EAAAA,CAAqB7E,CAAAA,CAAKuF,CAAC,CAAA,CAAIA,EACzD,CAKF,IAAMF,CAAAA,CACJhC,CAAAA,CACAuB,CAAAA,CACAxJ,CAAAA,CACAwJ,CAAAA,CACApB,CAAAA,CACAoB,CAAAA,CACAQ,CAAAA,CACAR,CAAAA,CACAU,CAAAA,CAGF,OAAOP,EAAAA,CAAyB,IAAA,CAAKM,CAAQ,CAAA,CACzCA,CAAAA,CAAS,OAAA,CAAQP,EAAAA,CAA4B,EAAE,CAAA,CAC/CO,CACN,CAQA,SAASG,EAAAA,CAAezE,CAAAA,CAAiC,CAEvD,OAAKA,CAAAA,CAAM,MAAA,CAIJ5E,CAAAA,EAAQ,CAAI4E,CAAAA,CAAM,MAAA,CAHhB,KAIX,CA+BO,SAAS0E,EAAAA,CACd1K,CAAAA,CAMY,CACZ,OAAO4J,EAAAA,CAAO,GAAA,CAAI5J,CAAa,CACjC,CAUO,SAAS2K,GACd3K,CAAAA,CACAd,CAAAA,CACAyH,CAAAA,CACAC,CAAAA,CACM,CACN,GAAID,CAAAA,GAAQ,CAAA,CAAG,CACbiE,EAAAA,CAAY5K,CAAG,CAAA,CACf,MACF,CAEA,IAAM6K,CAAAA,CAAOzJ,CAAAA,EAAQ,CACf0J,CAAAA,CAAQnE,CAAAA,CAAMA,CAAAA,CAAM,GAAA,CAAO,CAAA,CAC3BoE,CAAAA,CAAcnE,CAAAA,CAAYA,CAAAA,CAAY,GAAA,CAAO,CAAA,CAEnDgD,EAAAA,CAAO,GAAA,CAAI5J,CAAAA,CAAK,CACd,IAAA,CAAAd,CAAAA,CACA,IAAA,CAAA2L,CAAAA,CACA,KAAA,CAAOE,CAAAA,CAAc,CAAA,CAAIF,CAAAA,CAAOE,CAAAA,CAAc,MAAA,CAC9C,MAAA,CAAQpE,CAAAA,GAAQ,EAAA,CAAK,MAAA,CAAYkE,CAAAA,CAAOC,CAC1C,CAAC,CAAA,CAEGA,CAAAA,CAAQ,CAAA,EACVvH,CAAAA,CACE,IAAA,CAAOvD,CAAAA,CACP,IAAM,CACJ4K,EAAAA,CAAY5K,CAAAA,CAAK,IAAI,EACvB,CAAA,CACA8K,CACF,EAEJ,CAQO,SAASF,EAAAA,CAAY5K,CAAAA,CAAagL,CAAAA,CAAyB,KAAA,CAAa,CAC7E,GAAIA,CAAAA,CAAe,CACjB,IAAMhF,CAAAA,CAAQ0E,EAAAA,CAAS1K,CAAG,CAAA,CAG1B,GAAI,CAACgG,CAAAA,EAAS,CAACyE,EAAAA,CAAezE,CAAK,CAAA,CACjC,MAEJ,CAEA4D,EAAAA,CAAO,MAAA,CAAO5J,CAAG,EACnB,CAgBA,eAAsBiL,EAAAA,CAMpBjL,CAAAA,CACAkL,CAAAA,CACAC,CAAAA,CAMQ,CAER,GAAI,CAACnL,CAAAA,CACH,OAAO,IAAA,CAGT,IAAMgG,CAAAA,CAAQ0E,EAAAA,CACZ1K,CACF,CAAA,CAEA,GAAI,CAACgG,CAAAA,CACH,OAAO,IAAA,CAGT,IAAMoF,CAAAA,CAAcjM,CAAAA,CAAS+L,CAAO,CAAA,CAAI7L,CAAAA,CAAe6L,CAAO,CAAA,CAAIA,CAAAA,CAE5DG,CAAAA,CAAkB,CACtB,GAAGrF,CAAAA,CAAM,IAAA,CACT,KAAMoF,CACR,CAAA,CAEME,CAAAA,CAAe,CACnB,GAAGtF,CAAAA,CACH,IAAA,CAAMqF,CACR,CAAA,CAKA,OAHAzB,EAAAA,CAAO,GAAA,CAAI5J,CAAAA,CAAKsL,CAAY,CAAA,CAC5B/D,CAAAA,CAAkBvH,CAAAA,CAAKqL,CAAe,CAAA,CAElCF,CAAAA,EAAYA,CAAAA,CAAS,OAAA,CAChB,MAAMjF,EAAAA,CAAWlG,CAAG,CAAA,CAGtB,IACT,CAcO,SAASuL,CAAAA,CAMdC,CAAAA,CACAC,CAAAA,CACApD,CAAAA,CAM0E,CAE1E,GAAI,CAACmD,CAAAA,EAAYC,CAAAA,GAAc,MAAA,EAAaA,CAAAA,GAAc,IAAA,CACxD,OAAO,IAAA,CAIT,IAAMC,CAAAA,CAASrD,CAAAA,CAAc,WAAA,EAAeV,CAAAA,CAAc,WAAA,CAK1D,GAJI+D,CAAAA,EAAUA,CAAAA,CAAOrD,CAAa,CAAA,EAI9BA,CAAAA,CAAc,KAAA,EAASA,CAAAA,CAAc,KAAA,GAAU,QAAA,CACjD,OAAO,IAAA,CAIT,IAAMrC,CAAAA,CAAQ0E,EAAAA,CACZc,CACF,CAAA,CAEA,OAAKxF,CAAAA,CAIayE,EAAAA,CAAezE,CAAK,CAAA,EAIpC4E,EAAAA,CAAYY,CAAQ,CAAA,CACb,IAAA,EAIFxF,CAAAA,CAAM,IAAA,CAZJ,IAaX,CASO,SAAS2F,EAAAA,CAMdC,CAAAA,CACAvD,CAAAA,CAMAwD,CAAAA,CAAmB,KAAA,CACb,CAEN,IAAML,CAAAA,CAAWnD,CAAAA,CAAc,QAAA,CAE/B,GAAImD,CAAAA,CAAU,CACZ,IAAMC,CAAAA,CAAYpD,CAAAA,CAAc,SAAA,CAC1ByD,CAAAA,CAAYzD,CAAAA,CAAc,SAAA,CAI9BoD,CAAAA,GACC,CAACI,CAAAA,EAAWxD,CAAAA,CAAc,WAAA,CAAA,EAC3B,EAAEyD,CAAAA,EAAaA,CAAAA,CAAUF,CAAAA,CAAQvD,CAAa,CAAA,CAAA,EAE9CsC,EAAAA,CAASa,CAAAA,CAAUI,CAAAA,CAAQH,CAAAA,CAAWpD,CAAAA,CAAc,SAAS,CAAA,CAG/Dd,CAAAA,CAAkBiE,CAAAA,CAAUI,CAAM,CAAA,CAClChH,EAAAA,CAAe4G,CAAQ,CAAA,CAEvB,IAAMO,CAAAA,CAAe1D,CAAAA,CAAc,QAAA,CAE/B0D,CAAAA,EACFnH,EAAAA,CAAemH,CAAY,EAE/B,CACF,CCxdA,eAAsBC,EAAAA,CAMpBrJ,CAAAA,CACc,CAEd,GAAI,CAACA,CAAAA,CACH,OAAO,IAAA,CAIT,IAAIsJ,CAAAA,CAAetJ,CAAAA,CAAsB,OAAA,EAAS,GAAA,CAAIrE,CAAY,CAAA,CAE9D2N,CAAAA,CAEFA,CAAAA,CAAcA,CAAAA,CAAY,WAAA,EAAY,CAAE,IAAA,EAAK,CAE7CA,CAAAA,CAAc,EAAA,CAIhB,IAAMC,CAAAA,CAAWD,CAAAA,CAAY,KAAA,CAAM,GAAA,CAAK,CAAC,CAAA,CAAE,CAAC,CAAA,CAExC/M,CAAAA,CAEJ,GAAI,CACF,GAAIgN,CAAAA,CAAS,QAAA,CAAS9N,CAAgB,CAAA,EAAK8N,CAAAA,CAAS,QAAA,CAAS,OAAO,CAAA,CAClEhN,CAAAA,CAAO,MAAMyD,CAAAA,CAAS,IAAA,EAAK,CAAA,KAAA,GAAA,CAE1BuJ,CAAAA,CAAS,QAAA,CAAS,qBAAqB,CAAA,EACtCA,CAAAA,CAAS,QAAA,CACP/N,CAAAA,CAA2B,uBAC7B,CAAA,GACF,OAAOwE,CAAAA,CAAS,QAAA,GAAajE,CAAAA,CAE7BQ,CAAAA,CAAO,MAAMyD,CAAAA,CAAS,QAAA,EAAS,CAAA,KAAA,GAE/BuJ,CAAAA,CAAS,UAAA,CAAW,QAAQ,CAAA,EAC5BA,CAAAA,CAAS,UAAA,CAAW,QAAQ,CAAA,EAC5BA,CAAAA,CAAS,UAAA,CAAW,QAAQ,CAAA,EAC5BA,CAAAA,CAAS,QAAA,CAAS/N,CAAAA,CAA2B,cAAc,CAAA,EAC3D+N,CAAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EACvBA,CAAAA,CAAS,QAAA,CAAS,KAAK,CAAA,CAEvBhN,CAAAA,CAAO,MAAMyD,CAAAA,CAAS,WAAA,EAAY,CAAA,KAAA,GAElCzD,CAAAA,CAAO,MAAMyD,CAAAA,CAAS,IAAA,EAAK,CAEvB,OAAOzD,CAAAA,GAAST,CAAAA,CAAQ,CAC1B,IAAM0N,CAAAA,CAAUjN,CAAAA,CAAK,IAAA,EAAK,CAC1B,GACGiN,CAAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAKA,CAAAA,CAAQ,QAAA,CAAS,GAAG,GAC/CA,CAAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAKA,CAAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,CAEhD,GAAI,CACFjN,CAAAA,CAAO,IAAA,CAAK,KAAA,CAAMiN,CAAO,EAC3B,CAAA,KAAQ,CAER,CAEJ,CAGJ,CAAA,KAAiB,CAEfjN,CAAAA,CAAO,KACT,CAEA,OAAOA,CACT,CAUO,IAAMkN,EAAAA,CAAkB,CAM7BzJ,CAAAA,CAMAwH,CAAAA,CACAjI,CAAAA,CAKW,IAAA,GAC2D,CACtE,IAAMmK,CAAAA,CAAkBlC,CAAAA,CAAO,eAAA,CACzBqB,CAAAA,CAAWrB,CAAAA,CAAO,QAAA,CAClBmC,CAAAA,CAAYrB,EAAAA,CAAO,IAAA,CAAK,IAAA,CAAMO,CAAkB,CAAA,CAQtD,GAAI,CAAC7I,CAAAA,CACH,OAAO,CACL,EAAA,CAAI,KAAA,CAEJ,KAAA,CAAAT,CAAAA,CACA,IAAA,CAAMmK,CAAAA,EAAmB,IAAA,CACzB,OAAA,CAAS,IAAA,CACT,MAAA,CAAAlC,CAAAA,CACA,MAAA,CAAQmC,CAAAA,CACR,UAAA,CAAY,KAAA,CACZ,SAAA,CAAW,KAAA,CACX,OAAA,CAAS,IACX,CAAA,CAQF,IAAMC,CAAAA,CACJ,OAAO,QAAA,GAAa7N,CAAAA,EAAYiE,CAAAA,YAAoB,QAAA,CAElDzD,CAAAA,CAAOyD,CAAAA,CAAS,IAAA,CAIlB0J,CAAAA,GAAoB,MAAA,GAElBnN,CAAAA,EAAS,IAAA,EACR,OAAOA,CAAAA,GAASV,CAAAA,EAAU,MAAA,CAAO,IAAA,CAAKU,CAAI,CAAA,CAAE,MAAA,GAAW,CAAA,CAAA,GAE1DyD,CAAAA,CAAS,IAAA,CAAOzD,CAAAA,CAAOmN,CAAAA,CAAAA,CAGrBlC,CAAAA,CAAO,eAAA,GACTxH,CAAAA,CAAS,IAAA,CAAOzD,CAAAA,CAAOwC,EAAAA,CAAYxC,CAAI,CAAA,CAAA,CAGrCiL,CAAAA,CAAO,MAAA,GACTxH,CAAAA,CAAS,IAAA,CAAOzD,CAAAA,CAAOiL,CAAAA,CAAO,MAAA,CAAOjL,CAAI,CAAA,CAAA,CAG3C,IAAM0C,CAAAA,CAAUD,CAAAA,CAAegB,CAAAA,CAAS,OAAO,CAAA,CAG/C,OAAI4J,CAAAA,CACK,CACL,IAAA,CAAM5J,CAAAA,CAAS,KACf,QAAA,CAAUA,CAAAA,CAAS,QAAA,CACnB,EAAA,CAAIA,CAAAA,CAAS,EAAA,CACb,UAAA,CAAYA,CAAAA,CAAS,UAAA,CACrB,IAAA,CAAMA,CAAAA,CAAS,IAAA,CACf,GAAA,CAAKA,CAAAA,CAAS,GAAA,CACd,MAAA,CAAQA,CAAAA,CAAS,MAAA,CACjB,UAAA,CAAYA,CAAAA,CAAS,UAAA,CAGrB,IAAA,CAAM,IACJ,OAAA,CAAQ,OAAA,CACNzD,CAAAA,YAAgB,WAAA,CAAc,IAAI,IAAA,CAAK,CAACA,CAAI,CAAC,CAAA,CAAI,IAAI,IACvD,CAAA,CACF,IAAA,CAAM,IAAM,OAAA,CAAQ,OAAA,CAAQA,CAAoB,CAAA,CAChD,IAAA,CAAM,IAAM,OAAA,CAAQ,OAAA,CAAQA,CAAc,CAAA,CAC1C,KAAA,CAAO,IAAMyD,CAAAA,CAAS,KAAA,EAAM,CAC5B,WAAA,CAAa,IACX,OAAA,CAAQ,OAAA,CACNzD,CAAAA,YAAgB,WAAA,CAAcA,CAAAA,CAAO,IAAI,WAAA,CAAY,CAAC,CACxD,CAAA,CACF,QAAA,CAAU,IACR,OAAA,CAAQ,OAAA,CAAQA,CAAAA,YAAgB,QAAA,CAAWA,CAAAA,CAAO,IAAI,QAAU,CAAA,CAClE,KAAA,CAAO,IACL,OAAA,CAAQ,OAAA,CACN,IAAI,UAAA,CACFA,CAAAA,YAAgB,WAAA,CAAcA,CAAAA,CAAO,IAAI,WAAA,CAAY,CAAC,CACxD,CACF,CAAA,CAEF,KAAA,CAAAgD,CAAAA,CACA,IAAA,CAAAhD,CAAAA,CACA,OAAA,CAAA0C,CAAAA,CACA,MAAA,CAAAuI,CAAAA,CACA,MAAA,CAAQmC,CAAAA,CACR,UAAA,CAAY,KAAA,CACZ,SAAA,CAAW3J,CAAAA,CAAS,EAAA,EAAM,CAACT,CAAAA,CAC3B,OAAA,CAAS,CAAC,CAACA,CACb,CAAA,EAIE/C,CAAAA,CAASwD,CAAQ,CAAA,GACnBA,CAAAA,CAAS,KAAA,CAAQT,CAAAA,CACjBS,CAAAA,CAAS,OAAA,CAAUf,CAAAA,CACnBe,CAAAA,CAAS,UAAA,CAAa,KAAA,CACtBA,CAAAA,CAAS,MAAA,CAAS2J,CAAAA,CAClB3J,CAAAA,CAAS,UAAYA,CAAAA,CAAS,EAAA,EAAM,CAACT,CAAAA,CACrCS,CAAAA,CAAS,OAAA,CAAU,CAAC,CAACT,CAAAA,CAAAA,CAGhBS,CAAAA,CACT,CAAA,CC1OA,SAAS6J,EAAAA,CAAkBC,CAAAA,CAAmC,CAC5D,IAAMjL,CAAAA,CAAK,IAAA,CAAK,KAAA,CAAMiL,CAAU,CAAA,CAAIrL,CAAAA,EAAQ,CAE5C,OAAK,KAAA,CAAMI,CAAE,CAAA,CAGN,IAAA,CAFE,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMA,CAAE,CAAC,CAGrC,CAaO,SAASkL,EAAAA,CACdC,CAAAA,CACe,CACf,GAAI,CAACA,CAAAA,CACH,OAAO,IAAA,CAGT,IAAM/K,CAAAA,CAAU+K,CAAAA,CAAiB,OAAA,EAAW,EAAC,CACvCC,CAAAA,CAAahL,CAAAA,CAAQ,aAAa,CAAA,CAExC,GAAIgL,CAAAA,CAAY,CAEd,IAAMlJ,CAAAA,CAAU,MAAA,CAAOkJ,CAAU,CAAA,CAEjC,GAAI,CAAC,KAAA,CAAMlJ,CAAO,CAAA,EAAKA,CAAAA,EAAW,CAAA,CAChC,OAAOA,CAAAA,CAAU,GAAA,CAGnB,IAAMlC,CAAAA,CAAKgL,EAAAA,CAAkBI,CAAU,CAAA,CAEvC,GAAIpL,CAAAA,GAAO,IAAA,CACT,OAAOA,CAEX,CAGA,IAAMqL,CAAAA,CAAkB,iBAAA,CAIlBC,CAAAA,CACJlL,CAAAA,CAAQiL,CAAAA,CAAkB,QAAQ,CAAA,EAClCjL,CAAAA,CAAQ,IAAA,CAAOiL,CAAAA,CAAkB,QAAQ,CAAA,CAE3C,GAAIC,CAAAA,CAAqB,CACvB,IAAMpJ,CAAAA,CAAU,MAAA,CAAOoJ,CAAmB,CAAA,CAE1C,GAAI,CAAC,KAAA,CAAMpJ,CAAO,CAAA,CAChB,OAAOA,CAAAA,CAAU,GAErB,CAIA,IAAMqJ,CAAAA,CACJnL,CAAAA,CAAQiL,CAAAA,CAAkB,KAAK,CAAA,EAAKjL,CAAAA,CAAQ,IAAA,CAAOiL,CAAAA,CAAkB,KAAK,CAAA,CAE5E,OAAIE,CAAAA,CACKP,EAAAA,CAAkBO,CAAgB,CAAA,CAGpC,IACT,CAkBA,eAAsBC,EAAAA,CAMpBC,CAAAA,CAMA9C,CAAAA,CAC4E,CAC5E,GAAM,CACJ,OAAA,CAAA+C,CAAAA,CAAU,CAAA,CACV,KAAA,CAAAC,CAAAA,CAAQ,CAAA,CACR,OAAA,CAAAC,CAAAA,CAAU,CAAA,CACV,QAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CAAU,EAAC,CACX,WAAA,CAAAC,CACF,CAAA,CAAIpD,CAAAA,CAEAqD,CAAAA,CAAU,CAAA,CACVC,CAAAA,CAAWN,CAAAA,CACTO,CAAAA,CAAaR,CAAAA,CAAU,CAAA,CAAIA,CAAAA,CAAU,CAAA,CACvCtB,CAAAA,CAEJ,KAAO4B,CAAAA,EAAWE,CAAAA,EAAY,CAG5B,GAAIF,CAAAA,CAAU,CAAA,EAAK5B,CAAAA,CAAS,CAC1B,IAAM+B,CAAAA,CAAM/B,CAAAA,CAAO,MAAA,CACbgC,CAAAA,CAAUD,CAAAA,CAAI,OAAA,CAEhBC,CAAAA,GACF,MAAMvL,CAAAA,CAAkBuL,CAAAA,CAAShC,CAAAA,CAAQ4B,CAAO,CAAA,CAI5CG,CAAAA,CAAI,UAAA,GACNA,CAAAA,CAAI,QAAA,CAAWA,CAAAA,CAAI,QAAA,CACnBA,CAAAA,CAAI,QAAA,CAAWzD,CAAAA,CAAiByD,CAAAA,CAAK,KAAK,CAAA,CAAA,EAGhD,CAKA/B,CAAAA,CAAS,MAAMqB,CAAAA,CAAUO,CAAAA,CAAU,CAAA,CAAGA,CAAO,CAAA,CAC7C,IAAMtL,CAAAA,CAAQ0J,CAAAA,CAAO,KAAA,CAGrB,GAAI,CAAC1J,CAAAA,CAAO,CACV,GAAIqL,CAAAA,EAAeC,CAAAA,CAAUE,CAAAA,EACD,MAAMH,CAAAA,CAAY3B,CAAAA,CAAQ4B,CAAO,CAAA,CAEpC,CACrB,MAAMjM,CAAAA,CAAgBkM,CAAQ,CAAA,CAC9BA,CAAAA,EAAYL,CAAAA,EAAW,CAAA,CACvBK,CAAAA,CAAW,IAAA,CAAK,GAAA,CAAIA,CAAAA,CAAUJ,CAAAA,EAAYI,CAAQ,CAAA,CAClDD,CAAAA,EAAAA,CACA,QACF,CAGF,KACF,CAWA,GAR2B,MAAMK,EAAAA,CAC/BjC,CAAAA,CACA4B,CAAAA,CACAE,CAAAA,CACAH,CAAAA,CACAD,CACF,CAAA,CAGE,MAKF,GAAIpL,CAAAA,CAAM,MAAA,GAAW,GAAA,EAAOA,CAAAA,CAAM,MAAA,GAAW,GAAA,CAAK,CAEhD,IAAM4L,CAAAA,CAAepB,EAAAA,CAAgBd,CAAM,CAAA,CAGvCkC,CAAAA,GAAiB,IAAA,GACnBL,CAAAA,CAAWK,CAAAA,EAEf,CAEA,MAAMvM,CAAAA,CAAgBkM,CAAQ,CAAA,CAC9BA,CAAAA,EAAYL,CAAAA,EAAW,CAAA,CACvBK,CAAAA,CAAW,IAAA,CAAK,GAAA,CAAIA,CAAAA,CAAUJ,CAAAA,EAAYI,CAAQ,CAAA,CAClDD,CAAAA,GACF,CAEA,OAAO5B,CACT,CAqBA,eAAsBiC,EAAAA,CAMpBjC,CAAAA,CACA4B,CAAAA,CACAE,CAAAA,CACAH,CAAAA,CAMAD,CAAAA,CAAoB,EAAC,CACH,CAIlB,GAAIE,CAAAA,GAAYE,CAAAA,CACd,OAAO,KAAA,CAGT,IAAIK,CAAAA,CAAiC,IAAA,CAGrC,OAAIR,CAAAA,GAEFQ,CAAAA,CADe,MAAMR,CAAAA,CAAY3B,CAAAA,CAAQ4B,CAAO,CAAA,CAI5CO,CAAAA,GAAmB,IAAA,CAAA,CACd,CAACA,CAAAA,CAIL,CAAA,CAAET,CAAAA,EAAW,EAAC,EAAG,QAAA,CAAS1B,CAAAA,CAAO,KAAA,EAAO,MAAA,EAAU,CAAC,CAC5D,CCjPA,eAAsBoC,EAAAA,CAMpBf,CAAAA,CAMAgB,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CAAc,CAAA,CACdC,CAAAA,CAAe,CAAA,CAC6D,CAC5E,GAAI,CAACH,CAAAA,CACH,OAAOhB,CAAAA,EAAU,CAGnB,IAAIoB,CAAAA,CAAiB,CAAA,CACjBzC,CAAAA,CAEJ,KAAA,CAAOuC,CAAAA,GAAgB,CAAA,EAAKE,CAAAA,CAAiBF,CAAAA,IACvCC,CAAAA,CAAe,CAAA,EACjB,MAAM7M,CAAAA,CAAgB6M,CAAY,CAAA,CAGpCxC,CAAAA,CAAS,MAAMqB,CAAAA,EAAU,CAEzBoB,CAAAA,EAAAA,CAGG,EAAAF,CAAAA,CAAc,CAAA,EAAKE,CAAAA,EAAkBF,CAAAA,EACtC,CAACF,CAAAA,EACAC,CAAAA,EAAqBA,CAAAA,CAAkBtC,CAAAA,CAAQyC,CAAc,CAAA,CAAA,CAAA,EAKhE,MAAM9M,CAAAA,CAAgB0M,CAAe,CAAA,CAGvC,OAAOrC,CACT,CC7CA,eAAsB0C,EAAAA,CAMpBxI,CAAAA,CACAmH,CAAAA,CAKA5E,CAAAA,CAM4E,CAC5E,IAAMuD,CAAAA,CAAS,MAAMqB,CAAAA,CAAUnH,CAAmB,CAAA,CAC5C5D,CAAAA,CAAQ0J,CAAAA,CAAO,KAAA,CAErB,GAAI,CAAC1J,CAAAA,CAEH,OAAAyJ,EAAAA,CAAoBC,CAAAA,CAAQvD,CAAa,CAAA,CAElCuD,CAAAA,CAKLvD,CAAAA,CAAc,OAAA,EAChB,MAAMhG,CAAAA,CAAkBgG,CAAAA,CAAc,OAAA,CAASnG,CAAK,CAAA,CAKtD,IAAMqM,CAAAA,CAAcrM,CAAAA,CAAM,WAAA,CAY1B,GAVI,CAACqM,CAAAA,EAAelG,CAAAA,CAAc,MAAA,EAChCmG,EAAAA,CAAOnG,CAAAA,CAAe,aAAA,CAAenG,CAAsB,CAAA,CAI7DyJ,EAAAA,CAAoBC,CAAAA,CAAQvD,CAAAA,CAAe,IAAI,CAAA,CAGrB,CAACkG,CAAAA,EAAelG,CAAAA,CAAc,eAAA,CAEjC,CACrB,IAAMoG,CAAAA,CAAWpG,CAAAA,CAAc,QAAA,CAE/B,GAAIoG,CAAAA,GAAa1P,EAAAA,CACf,OAAO,OAAA,CAAQ,MAAA,CAAOmD,CAAK,CAAA,CAIzBuM,CAAAA,GAAa,QAAA,EACf,MAAM,IAAI,OAAA,CAAQ,IAAM,IAAI,EAEhC,CAEA,OAAO7C,CACT,CAEO,SAAS8C,EAAAA,CAOdxM,CAAAA,CACAS,CAAAA,CAMA0F,CAAAA,CAMM,CACNnG,CAAAA,CAAM,MAAA,CAASA,CAAAA,CAAM,MAAA,EAAUS,CAAAA,EAAU,MAAA,EAAU,CAAA,CACnDT,CAAAA,CAAM,UAAA,CAAaA,CAAAA,CAAM,UAAA,EAAcS,CAAAA,EAAU,UAAA,EAAc,EAAA,CAC/DT,CAAAA,CAAM,MAAA,CAASA,CAAAA,CAAM,OAAA,CAAUmG,CAAAA,CAC/BnG,CAAAA,CAAM,QAAA,CAAWS,CAAAA,CACjBT,CAAAA,CAAM,WAAA,CAAcA,CAAAA,CAAM,IAAA,GAASvD,GACrC,CAQA,SAAS6P,EAAAA,CACPtG,CAAAA,CAAAA,GACG3F,CAAAA,CACG,CACN,IAAMiM,CAAAA,CAAStG,CAAAA,CAAU,OAErBsG,CAAAA,EAAUA,CAAAA,CAAO,IAAA,EACnBA,CAAAA,CAAO,IAAA,CAAK,GAAGjM,CAAI,EAEvB,CC/FA,IAAMoM,EAAAA,CAAmB,MAAA,CAAO,MAAA,CAAO,CACrC,UAAA,CAAY,IACd,CAAC,CAAA,CAqBD,eAAsBC,EAAAA,CAMpBvO,CAAAA,CACA6H,CAAAA,CAKW,IAAA,CACiE,CAI5E,GAAIA,CAAAA,EAAa,OAAOA,CAAAA,CAAU,QAAA,EAAa,QAAA,CAAU,CACvD,IAAM2G,CAAAA,CAAStD,CAAAA,CAKbrD,CAAAA,CAAU,QAAA,CAAUA,CAAAA,CAAU,SAAA,CAAWA,CAAS,CAAA,CAEpD,GAAI2G,CAAAA,CACF,OAAOA,CAEX,CAEA,IAAMC,CAAAA,CAAgB7G,EAAAA,CAKpB5H,CAAAA,CAAK6H,CAAS,CAAA,CAEV,CACJ,OAAA,CAAAjE,CAAAA,CACA,WAAA,CAAA8K,CAAAA,CACA,QAAA,CAAAvD,CAAAA,CACA,UAAA,CAAAtH,CAAAA,CACA,SAAA,CAAAuH,CAAAA,CACA,SAAA,CAAA7E,CAAAA,CACA,cAAA,CAAAE,CAAAA,CACA,kBAAA,CAAAC,CAAAA,CACA,eAAA,CAAAkH,CAAAA,CAAkB,CACpB,CAAA,CAAIa,CAAAA,CACEE,CAAAA,CAAiBvD,CAAAA,GAAc,MAAA,EAAa7E,CAAAA,GAAc,MAAA,CAE1DqI,CAAAA,CAAgB,CAAC,EACrBzD,CAAAA,EACAvH,CAAAA,EACAC,CAAAA,EACA8K,CAAAA,EACAD,CAAAA,EACAjI,CAAAA,EACAC,CAAAA,CAAAA,CAGEmI,CAAAA,CAA2B,IAAA,CAQ/B,GALID,CAAAA,GACFC,CAAAA,CAAYhF,CAAAA,CAAiB4E,CAAa,CAAA,CAAA,CAIxCI,CAAAA,EAAaF,CAAAA,CAAgB,CAC/B,IAAMH,CAAAA,CAAStD,CAAAA,CAKb2D,CAAAA,CAAWzD,CAAAA,CAAWqD,CAAa,CAAA,CAErC,GAAID,CAAAA,CACF,OAAOA,CAEX,CAGA,GAAIK,CAAAA,EAAahL,CAAAA,CAAY,CAC3B,IAAMiL,CAAAA,CAAWpK,EAAAA,CAEfmK,CAAAA,CAAWhL,CAAU,CAAA,CAEvB,GAAIiL,CAAAA,CACF,OAAOA,CAEX,CAEA,IAAMC,CAAAA,CAAcN,EAAc,KAAA,EAAS,EAAC,CACtC,CAAE,OAAA,CAAA5B,EAAAA,CAAU,CAAA,CAAG,YAAA,CAAAmC,EAAa,CAAA,CAAID,CAAAA,CAGhCE,EAAAA,CAAgB,MAAOxJ,CAAAA,CAAsB,KAAA,CAAO0H,EAAAA,CAAU,CAAA,GAAM,CAInEA,EAAAA,GACC0B,CAAAA,EAAa,CAACpJ,CAAAA,GACZc,CAAAA,CACoB2E,CAAAA,CACpB2D,CAAAA,CACAzD,CAAAA,CACAqD,CACF,CAAA,GAKEnE,EAAAA,CAASuE,CAAAA,CAAWP,EAAAA,CAAkBlD,CAAAA,CAAW7E,CAAS,CAAA,CAC1DW,CAAAA,CAAkB2H,CAAAA,CAAWP,EAAgB,CAAA,CAAA,CAG/CpH,CAAAA,CAAkB2H,CAAAA,CAAWP,EAAgB,CAAA,CAAA,CAKjDG,CAAAA,CAAc,QAAA,CAAWI,CAAAA,CAAAA,CAG3B,IAAM7O,CAAAA,CAAMyO,CAAAA,CAAc,GAAA,CAGpBpK,EAAAA,CAAaV,EAAAA,CACjBkL,CAAAA,CACA7O,CAAAA,CACA4D,CAAAA,CACAC,CAAAA,EAAc,CAAA,CACd,CAAC,CAAC6K,CAAAA,CAEF,CAAC,EAAE9K,CAAAA,GAAY,CAACuJ,EAAAA,EAAW6B,EAAAA,CAAAA,CAC7B,CAAA,CAIMhH,CAAAA,CAAgByG,CAAAA,CAEtBzG,CAAAA,CAAc,MAAA,CAAS3D,EAAAA,CAAW,MAAA,CAElC,IAAIkH,EAAAA,CAMAjJ,CAAAA,CAKO,IAAA,CAEX,GAAI,CACEmM,CAAAA,CAAc,SAAA,GAOZI,CAAAA,EAAahL,CAAAA,EAAc,CAACsJ,EAAAA,EAC9B,MAAM,IAAA,CAGR,MAAMnL,CAAAA,CAAkByM,CAAAA,CAAc,SAAA,CAAWzG,CAAa,CAAA,CAAA,CAIhE,IAAMhB,CAAAA,CAAKyH,CAAAA,CAAc,OAAA,CAkBzB,GAhBAnM,CAAAA,CAAY0E,CAAAA,CACR,MAAMA,CAAAA,CACJhH,CAAAA,CACAgI,CACF,CAAA,CACA,MAAM,KAAA,CACJhI,CAAAA,CACAgI,CACF,CAAA,CAQAlJ,CAAAA,CAASwD,CAAQ,CAAA,GAEf,OAAO,QAAA,GAAajE,CAAAA,EAAYiE,CAAAA,YAAoB,QAAA,CACtDA,CAAAA,CAAS,IAAA,CAAO0F,CAAAA,CAAc,MAAA,CAC1B,MAAMA,CAAAA,CAAc,MAAA,CAAO1F,CAAQ,CAAA,CACnC,MAAMqJ,EAAAA,CAAkBrJ,CAAQ,CAAA,CAC3B0E,CAAAA,GAEH,MAAA,GAAU1E,CAAAA,EAAY,MAAA,GAAUA,CAAAA,GAEpCA,CAAAA,CAAW,CAAE,IAAA,CAAMA,CAAS,CAAA,CAAA,CAAA,CAYhCA,CAAAA,CAAS,MAAA,CAAS0F,CAAAA,CAId1F,CAAAA,CAAS,EAAA,GAAO,KAAA,CAAA,EAAa,CAACA,CAAAA,CAAS,EAAA,CAAA,CACzC,MAAM,IAAIC,EAAAA,CACR,CAAA,EAAGyF,CAAAA,CAAc,MAAM,CAAA,IAAA,EAAOhI,CAAG,CAAA,iBAAA,EAAoBsC,CAAAA,CAAS,MAAA,EAAU,IAAI,CAAA,CAAA,CAC5E0F,CAAAA,CACA1F,CACF,CAAA,CAIJiJ,EAAAA,CAASQ,EAAAA,CAKPzJ,CAAAA,CAAU0F,CAAa,CAAA,CAEzB,IAAMkH,CAAAA,CAAaT,CAAAA,CAAc,UAAA,CAE7BS,CAAAA,EACF,MAAMlN,CAAAA,CAAkBkN,CAAAA,CAAY3D,EAAM,EAE9C,CAAA,MAAS4D,CAAAA,CAAQ,CACf,IAAMtN,CAAAA,CAAQsN,CAAAA,CAQdd,EAAAA,CACExM,CAAAA,CACAS,CAAAA,CACA0F,CACF,CAAA,CAGAuD,EAAAA,CAASQ,EAAAA,CAKPzJ,CAAAA,CAAU0F,CAAAA,CAAenG,CAAK,EAClC,CAEA,OAAO0J,EACT,CAAA,CAKM6D,EAAAA,CACJvC,EAAAA,CAAU,CAAA,CACN,CAACpH,CAAAA,CAAsB,KAAA,GACrBkH,EAAAA,CACE,CAAC0C,EAAAA,CAAGlC,CAAAA,GAAY8B,EAAAA,CAAcxJ,CAAAA,CAAqB0H,CAAO,CAAA,CAC1D4B,CACF,CAAA,CACFE,EAAAA,CAEAK,CAAAA,CAA2B,CAAC7J,CAAAA,CAAsB,KAAA,GACtDwI,EAAAA,CACExI,CAAAA,CACA2J,EAAAA,CACAX,CACF,CAAA,CAGIc,EAAAA,CAAmB3B,CAAAA,CACrBD,EAAAA,CACE2B,CAAAA,CACA1B,CAAAA,CACAa,CAAAA,CAAc,iBAAA,CACdA,CAAAA,CAAc,kBAAA,CACdA,CAAAA,CAAc,YAChB,CAAA,CACAa,CAAAA,EAAyB,CAG7B,OAAIT,CAAAA,GACEhL,CAAAA,EACFW,EAAAA,CAAmBqK,CAAAA,CAAWU,EAAgB,CAAA,CAAA,CAI5ChJ,CAAAA,EAAaE,CAAAA,EAAkBC,CAAAA,GACjCN,EAAAA,CACEyI,CAAAA,CACAS,CAAAA,CACA,MAAA,CACA/I,CAAAA,CACA+I,CAAAA,CACA,CAAC,CAAC7I,CAAAA,CACF,CAAC,CAACC,CACJ,CAAA,CAAA,CAIG6I,EACT,CClUA,SAASC,EAAAA,CAGP1F,CAAAA,CAAyC,CACzC,IAAM2F,CAAAA,CAAY3F,CAAAA,CAAO,SAAA,CAQzB,SAAS4F,CAAAA,CAAqBC,CAAAA,CAAqC,CACjE,OAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,IAAA,EAAOA,CAAY,CAAA,gBAAA,CAAkB,CAAA,CAE5C,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAC7B,CAEA,IAAMC,CAAAA,CAAsD,CAC1D,MAAA,CAAA9F,CAAAA,CACA,SAAA,CAAA2F,CAAAA,CASA,MAAM,OAAA,CAAQE,CAAAA,CAAc3H,CAAAA,CAAgB,EAAC,CAAG,CAE9C,IAAM6H,CAAAA,CAAiBJ,CAAAA,CAAUE,CAAY,CAAA,CACvCG,CAAAA,CACJD,CAAAA,EACC,CAAE,GAAA,CAAK,MAAA,CAAOF,CAAY,CAAE,CAAA,CACzB3P,CAAAA,CAAM8P,CAAAA,CAAgB,GAAA,CAG5B,GAAI9P,CAAAA,CAAI,UAAA,CAAW,IAAI,CAAA,CACrB,MAAM,IAAI,KAAA,CAAM,yCAAyC,CAAA,CAI3D,IAAM+P,CAAAA,CAAejP,EAAAA,CAAcd,CAAG,CAAA,CAElC6P,CAAAA,EAAgB,GAAA,GAAQ7P,CAAAA,CACtB0H,CAAAA,CAAaoI,CAAAA,CAAiB9H,CAAa,CAAA,CAC3CA,CAAAA,CACFN,CAAAA,CAAaA,CAAAA,CAAaoC,CAAAA,CAAQgG,CAAe,CAAA,CAAG9H,CAAa,CAAA,CAIrE,OAAOuG,EAAAA,CAAOvO,CAAAA,CAAK+P,CAAY,CACjC,CACF,CAAA,CAOA,OAAO,IAAI,KAAA,CACTH,CAAAA,CACA,CACE,GAAA,CAAII,CAAAA,CAASC,CAAAA,CAAc,CACzB,OAAIA,CAAAA,IAAQL,CAAAA,CACHA,CAAAA,CAAWK,CAA0C,CAAA,CAI1DR,CAAAA,CAAUQ,CAAI,CAAA,CACTL,CAAAA,CAAW,OAAA,CAAQ,IAAA,CAAK,IAAA,CAAMK,CAAI,CAAA,CAGpCP,CAAAA,CAAqB,IAAA,CAAK,IAAA,CAAMO,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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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 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 (Object.prototype.hasOwnProperty.call(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 = Object.prototype.hasOwnProperty.call(obj, '__proto__');\n const hasCtor = Object.prototype.hasOwnProperty.call(obj, 'constructor');\n const hasPrototype = Object.prototype.hasOwnProperty.call(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const keys = Object.keys(obj);\n\n keys.sort();\n\n const sortedObj = {} as Record;\n\n for (let i = 0, len = keys.length; i < len; i++) {\n const key = keys[i];\n\n sortedObj[key] = obj[key];\n }\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.includes('?')\n ? `${baseUrl}&${queryString}`\n : `${baseUrl}?${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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\n // Use hasOwnProperty for strict key existence check\n if (Object.prototype.hasOwnProperty.call(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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport async function delayInvocation(ms: number): Promise {\n return new Promise((resolve) =>\n setTimeout(() => {\n return resolve(true);\n }, ms),\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 if (isObject(headers)) {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 if (typeof interceptors === FUNCTION) {\n const value = await (interceptors as InterceptorFunction)(\n data,\n ...args,\n );\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n const value = await interceptor(data, ...args);\n\n if (value && isObject(data) && isObject(value)) {\n Object.assign(data, value);\n }\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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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\nfunction ensureListenerSet(key: string) {\n let set = listeners.get(key);\n\n if (!set) {\n set = new Set();\n listeners.set(key, set);\n }\n\n return set;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n ensureListenerSet(key).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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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 (\n mimeType.startsWith('image/') ||\n mimeType.startsWith('video/') ||\n mimeType.startsWith('audio/') ||\n mimeType.includes(APPLICATION_CONTENT_TYPE + 'octet-stream') ||\n mimeType.includes('pdf') ||\n mimeType.includes('zip')\n ) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 let customDecision: boolean | null = null;\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n customDecision = result;\n\n // Decision cascade:\n if (customDecision !== null) {\n return !customDecision;\n }\n }\n\n return !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger) {\n logger(requestConfig, 'FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || response?.statusText || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n\n/**\n * Logs messages or errors using the configured logger's `warn` method.\n *\n * @param {RequestConfig} reqConfig - Request config passed when making the request\n * @param {...(string | ResponseError)} args - Messages or errors to log.\n */\nfunction logger(\n reqConfig: RequestConfig,\n ...args: (string | ResponseError)[]\n): void {\n const logger = reqConfig.logger;\n\n if (logger && logger.warn) {\n logger.warn(...args);\n }\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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} to ${url} failed! Status: ${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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error(`Add ${endpointName} to 'endpoints'.`);\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\n throw new Error('Protocol-relative URLs are 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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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/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_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","key","replaceUrlPathParams","urlPathParams","match","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","resolve","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","MAX_WHEEL_MS","wheel","keyMap","position","timer","handleCallback","callback","result","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","idx","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","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","existing","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","buildFetcherConfig","merged","requestConfig","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","contentTypeValue","baseConfig","overrideConfig","targetConfig","mergeConfig","mergeInterceptors","property","baseInterceptor","newInterceptor","baseArr","newArr","base","override","baseNormalized","overrideNormalized","_cache","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADER_WHITELIST","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","bodyString","isCacheExpired","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","removeExpired","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","getCachedResponse","cacheKey","cacheTime","buster","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","contentType","mimeType","trimmed","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryAfterMs","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","pollingAttempt","withErrorHandling","isCancelled","strategy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","needsCacheKey","_cacheKey","inflight","retryConfig","resetTimeout","doRequestOnce","onResponse","_error","baseRequest","_","requestWithErrorHandling","doRequestPromise","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","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","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, 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\nconst 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 const safeObj = { ...obj };\n\n if (hasProto) delete safeObj.__proto__;\n if (hasCtor) delete (safeObj as any).constructor;\n if (hasPrototype) delete safeObj.prototype;\n\n return safeObj;\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 const sortedObj = {} 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 `:`, where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:`.\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) {\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(/:([a-zA-Z0-9_]+)/g, (match, key) => {\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 return encodeURIComponent(String(value));\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL contains a scheme (e.g., \"http://\", \"https://\").\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 url.includes('://');\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\nexport const delayInvocation = (ms: number): Promise =>\n new Promise((resolve) => setTimeout(resolve, ms, true));\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 if (hasOwn(headers, key)) {\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","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject } 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 && isObject(data) && isObject(v) && Object.assign(data, 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 status: number;\n statusText: string;\n config: RequestConfig;\n isCancelled: boolean;\n\n constructor(\n message: string,\n public request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n public response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.name = 'FetchError';\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\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 exceeds 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 * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { noop } 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 MAX_WHEEL_MS = WHEEL_SIZE * SECOND;\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\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 // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || ms > MAX_WHEEL_MS || ms % SECOND !== 0) {\n keyMap.set(key, [setTimeout(handleCallback.bind(null, [key, cb]), ms)]); // Store timeout ID instead of slot\n\n return;\n }\n\n // No need for Math.ceil here since ms is guaranteed by modulo above\n const seconds = ms / SECOND;\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\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 const idx = slotArr.findIndex(([k]) => k === key);\n\n if (idx !== -1) {\n slotArr.splice(idx, 1);\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?.[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];\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 */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex]) {\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 const handler = revalidateAll.bind(null, event, true);\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 */\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) {\n const existing = revalidators.get(key);\n\n if (existing) {\n // Update in-place to avoid allocating a new tuple array\n existing[0] = revalidatorFn;\n existing[1] = timeNow();\n existing[2] = ttl ?? DEFAULT_TTL;\n existing[3] = staleTime;\n existing[4] = bgRevalidatorFn;\n existing[5] = refetchOnFocus;\n existing[6] = refetchOnReconnect;\n } else {\n revalidators.set(key, [\n revalidatorFn,\n timeNow(),\n ttl ?? DEFAULT_TTL,\n staleTime,\n bgRevalidatorFn,\n refetchOnFocus,\n refetchOnReconnect,\n ]);\n }\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 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};\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 return mergeConfigs({}, sanitized, defaultConfig);\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 if (!reqConfig) {\n return buildFetcherConfig(url, getDefaultConfig());\n }\n\n const sanitized = sanitizeObject(reqConfig);\n const merged = mergeConfigs(defaultConfig, sanitized);\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 requestConfig.url = baseURL + 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 already have their own MIME types, don't override\n (typeof File !== UNDEFINED && body instanceof File) ||\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 !headers[CONTENT_TYPE]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\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', and 'onError'.\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 mergeInterceptors('onRequest', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onResponse', baseConfig, overrideConfig, targetConfig);\n mergeInterceptors('onError', baseConfig, overrideConfig, targetConfig);\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends 'onRequest' | 'onResponse' | 'onError' | 'onRetry',\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 return;\n }\n\n if (!baseInterceptor) {\n targetConfig[property] = newInterceptor;\n return;\n }\n\n if (!newInterceptor) {\n targetConfig[property] = baseInterceptor;\n return;\n }\n\n const baseArr = Array.isArray(baseInterceptor)\n ? baseInterceptor\n : [baseInterceptor];\n const newArr = Array.isArray(newInterceptor)\n ? newInterceptor\n : [newInterceptor];\n\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] =\n property === 'onResponse' ? newArr.concat(baseArr) : baseArr.concat(newArr);\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 if (overrideConfig[property]) {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n // Handle Headers instances which don't expose entries as own enumerable properties\n if (\n property === 'headers' &&\n ((base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers)\n ) {\n const baseNormalized = processHeaders(base);\n const overrideNormalized = processHeaders(override);\n targetConfig[property] = {\n ...baseNormalized,\n ...overrideNormalized,\n } as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...override,\n };\n }\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 { CacheEntry } from './types/cache-manager';\nimport { GET, STRING, UNDEFINED } from './constants';\nimport { isObject, sanitizeObject, sortObject, timeNow } 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>();\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 * All header names must be lowercase to match normalized request headers.\n */\nconst CACHE_KEY_HEADER_WHITELIST = new Set([\n // Content negotiation\n 'accept', // Affects response format (e.g. JSON, HTML)\n 'accept-language', // Affects localization of the response\n 'accept-encoding', // Affects response compression (e.g. gzip, br)\n\n // Authentication\n 'authorization', // Affects access to protected resources\n\n // Request body metadata\n 'content-type', // Affects how the request body is interpreted\n\n // Optional headers\n 'referer', // May influence behavior in some APIs\n 'origin', // Relevant in CORS or tenant-specific APIs\n 'user-agent', // Included only for reason if server returns client-specific content\n\n // Cookies — only if server uses session-based responses\n 'cookie', // Can fragment cache heavily; use only if necessary\n\n // Custom headers that may affect response content\n 'x-api-key', // Token-based access, often affects authorization\n 'x-requested-with', // AJAX requests (used historically for distinguishing frontend calls)\n 'x-client-id', // Per-client/partner identity; often used in multi-tenant APIs\n 'x-tenant-id', // Multi-tenant segmentation; often changes response per tenant\n 'x-user-id', // Explicit user context (less common, but may exist)\n\n 'x-app-version', // Used for version-specific behavior (e.g. mobile apps)\n 'x-feature-flag', // Controls feature rollout behavior server-side\n 'x-device-id', // Used when response varies per device/app instance\n 'x-platform', // e.g. 'ios', 'android', 'web' — used in apps that serve different content\n\n 'x-session-id', // Only if backend uses it to affect the response directly (rare)\n 'x-locale', // Sometimes used in addition to or instead of `accept-language`\n]);\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_HEADER_WHITELIST.has(keys[i].toLowerCase())) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\n : cacheStr;\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING) {\n bodyString = body.length < MIN_LENGTH_TO_HASH ? body : hash(body); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Append key=value and '&' directly to the result\n bodyString += key + '=' + value + '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (\n (typeof Blob !== UNDEFINED && body instanceof Blob) ||\n (typeof File !== UNDEFINED && body instanceof File)\n ) {\n bodyString = 'BF' + body.size + body.type;\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n bodyString = 'AB' + body.byteLength;\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 // 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 DELIMITER +\n bodyString;\n\n // Prevent cache poisoning by removal of control chars and unusual characters\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '')\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 addTimeout(\n 'c:' + key,\n () => {\n deleteCache(key, true);\n },\n ttlMs,\n );\n }\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\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}\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 const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\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 // Check if cache should be bypassed\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n if (buster && buster(requestConfig)) {\n return null;\n }\n\n if (requestConfig.cache && requestConfig.cache === 'reload') {\n return null; // Skip cache lookup entirely\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 // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n return entry.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\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 OBJECT,\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.\n *\n * @param response - The Response object to parse.\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): 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 let contentType = (response as Response).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 (mimeType.includes(APPLICATION_JSON) || mimeType.includes('+json')) {\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\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (typeof data === OBJECT && 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 return {\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 blob: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n ), // Lazily construct Blob from ArrayBuffer\n json: () => Promise.resolve(data as ResponseData), // Return the already parsed JSON data\n text: () => Promise.resolve(data as string), // Return the already parsed text data\n clone: () => response.clone(),\n arrayBuffer: () =>\n Promise.resolve(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ), // Return the ArrayBuffer directly\n formData: () =>\n Promise.resolve(data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: () =>\n Promise.resolve(\n new Uint8Array(\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0),\n ),\n ),\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\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 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';\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 } = 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 // Check if we should retry based on successful response\n if (!error) {\n if (shouldRetry && attempt < maxRetries) {\n const shouldRetryResult = await shouldRetry(output, attempt);\n\n if (shouldRetryResult) {\n await delayInvocation(waitTime);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n continue;\n }\n }\n\n break;\n }\n\n // Determine if we should stop retrying\n const shouldStopRetrying = await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n );\n\n if (shouldStopRetrying) {\n break;\n }\n\n // If we should not stop retrying, continue to the next attempt\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (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 if (retryAfterMs !== null) {\n waitTime = retryAfterMs;\n }\n }\n\n await delayInvocation(waitTime);\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 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 *\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 * @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): 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 // 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 !(retryOn || []).includes(output.error?.status ?? 0);\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation } 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 *\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 * @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): 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);\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 await delayInvocation(pollingInterval);\n }\n\n return output!;\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 { DefaultParams, DefaultUrlParams, DefaultPayload } from './types';\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 if (!isCancelled && requestConfig.logger?.warn) {\n requestConfig.logger.warn('FETCH ERROR', error as ResponseError);\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 return Promise.reject(error);\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\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?.status || 0;\n error.statusText = error.statusText || 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} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport { generateCacheKey, getCachedResponse, setCache } from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION } 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\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 // 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\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 actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation = false, attempt = 0) => {\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 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 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\n response = (fn\n ? await fn(\n url,\n requestConfig,\n )\n : await fetch(\n url,\n requestConfig as RequestInit,\n )) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\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);\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 }\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 = false) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n baseRequest,\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 )\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 );\n }\n }\n\n return doRequestPromise;\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 { isAbsoluteUrl } 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 function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return Promise.resolve(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 const endpointConfig = endpoints[endpointName];\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (url.startsWith('//')) {\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 const mergedConfig = isAbsoluteUrl(url)\n ? // Merge endpoints configs for absolute URLs only if urls match\n 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) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (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