UNPKG

idmp

Version:

A lightweight TypeScript library for deduplicating and caching async function calls with automatic retries, designed for idempotent network requests in React and Node.js.

2 lines 2.56 kB
/*! idmp v4.1.0 | (c) github/haozi | MIT */ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.idmp={}))})(this,function(e){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var t=function(e){return e[e.UNSENT=0]=`UNSENT`,e[e.OPENING=1]=`OPENING`,e[e.ABORTED=2]=`ABORTED`,e[e.REJECTED=3]=`REJECTED`,e[e.RESOLVED=4]=`RESOLVED`,e}(t||{}),n=function(e){return e[e.retryCount=0]=`retryCount`,e[e.status=1]=`status`,e[e.pendingList=2]=`pendingList`,e[e.resolvedData=3]=`resolvedData`,e[e.rejectionError=4]=`rejectionError`,e[e.cachedPromiseFunc=5]=`cachedPromiseFunc`,e[e.timerId=6]=`timerId`,e[e._originalErrorStack=7]=`_originalErrorStack`,e}(n||{}),r=3e3,i=6048e5,a=()=>{},o=void 0,s=setTimeout,c=clearTimeout,l=(e,t)=>e>t?e:t,u=(e,t)=>e<t?e:t,d=e=>e<0?0:e>i?i:e,f={},p=e=>{let{maxRetry:t=30,maxAge:n=r,minRetryDelay:i=50,maxRetryDelay:o=5e3,onBeforeRetry:s=a,signal:c}=e||{};return{maxRetry:t,maxAge:d(n),minRetryDelay:i,maxRetryDelay:o,onBeforeRetry:s,f:n===1/0,signal:c}},m=e=>{if(!e)return;let t=f[e];t&&(t[n.timerId]&&c(t[n.timerId]),f[e]=o)},h=()=>{for(let e of Object.keys(f))m(e);f={}},g=(e,r,i)=>{if(!e)return r();let{maxRetry:a,minRetryDelay:c,maxRetryDelay:d,maxAge:h,onBeforeRetry:g,f:_,signal:v}=p(i);f[e]=f[e]||[0,t.UNSENT,[]];let y=f[e],b=()=>{y[n.status]=t.UNSENT,y[n.resolvedData]=y[n.rejectionError]=o},x=()=>{let t=y[n.pendingList].length;for(let e=0;e<t;++e)y[n.pendingList][e][0](y[n.resolvedData]);y[n.pendingList]=[],_||(y[n.timerId]=s(()=>{m(e)},h))},S=()=>{let t=y[n.pendingList].length,r;r=t-a,(r<0||!isFinite(t))&&(r=l(1,y[n.pendingList].length-3));for(let e=0;e<r;++e)y[n.pendingList][e][1](y[n.rejectionError]);m(e)},C=()=>new Promise((i,o)=>{if(!y[n.cachedPromiseFunc]&&(y[n.cachedPromiseFunc]=r),y[n.status]===t.RESOLVED){i(y[n.resolvedData]);return}if(v){if(v.aborted)return;v.addEventListener(`abort`,()=>{b(),y[n.rejectionError]=new DOMException(v.reason,`AbortError`),S()})}y[n.status]===t.UNSENT?(y[n.status]=t.OPENING,y[n.pendingList].push([i,o]),y[n.cachedPromiseFunc]().then(e=>{y[n.resolvedData]=e,x(),y[n.status]=t.RESOLVED}).catch(r=>{y[n.status]=t.REJECTED,y[n.rejectionError]=r,++y[n.retryCount],y[n.retryCount]>a?S():(g(r,{globalKey:e,retryCount:y[n.retryCount]}),b(),s(C,u(d,c*Math.pow(2,y[n.retryCount]-1))))})):y[n.status]===t.OPENING&&y[n.pendingList].push([i,o])});return C()};g.flush=m,g.flushAll=h,g._s=o,e.default=g,e.idmp=g,e.getOptions=p});