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 3.63 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;function _(e,t,n,r,i,a,o){try{var s=e[a](o),c=s.value}catch(e){n(e);return}s.done?t(c):Promise.resolve(c).then(r,i)}function v(e){return function(){var t=this,n=arguments;return new Promise(function(r,i){var a=e.apply(t,n);function o(e){_(a,r,i,o,s,`next`,e)}function s(e){_(a,r,i,o,s,`throw`,e)}o(void 0)})}}var y=void 0,b=`@idmp/v4/`,x=e=>`${b}${e}`,S=e=>{let t;try{t=window[e]}catch(e){}let n=e=>{if(e)try{let n=x(e);t.removeItem(n)}catch(e){}};return{get:e=>{if(!e)return;let r=x(e),i;try{if(i=JSON.parse(t.getItem(r)||``),i===y)return;let{t:e,a,d:o}=i;if(Date.now()-e>a){n(r);return}return o}catch(e){}},set:(e,n,r)=>{if(!e)return;let i=x(e);try{t.setItem(i,JSON.stringify({t:Date.now(),a:r,d:n}))}catch(e){}},remove:n,clear:()=>{try{for(let e=t.length-1;e>=0;e--){let r=t.key(e);r&&r.startsWith(b)&&n(r)}}catch(e){}}}};e.default=(e,t=`sessionStorage`)=>{let n=S(t),r=(t,r,i)=>{let a=p(i);return e(t,v(function*(){let e=n.get(t);if(e!==y)return e;let i=yield r();return i!==y&&n.set(t,i,a.maxAge),i}),i)};return r.flush=t=>{e.flush(t),n.remove(t)},r.flushAll=()=>{e.flushAll(),n.clear()},r},e.getCacheKey=x});