tryo 0.13.9 → 0.13.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +35 -24
- package/dist/index.d.ts +35 -24
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var F=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var he=Object.prototype.hasOwnProperty;var Re=(e,r,t)=>r in e?F(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var Ce=(e,r)=>{for(var t in r)F(e,t,{get:r[t],enumerable:!0})},xe=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of be(r))!he.call(e,o)&&o!==t&&F(e,o,{get:()=>r[o],enumerable:!(n=we(r,o))||n.enumerable});return e};var ge=e=>xe(F({},"__esModule",{value:!0}),e);var d=(e,r,t)=>Re(e,typeof r!="symbol"?r+"":r,t);var Ue={};Ce(Ue,{RetryStrategies:()=>ne,TypedError:()=>f,all:()=>ye,allOrThrow:()=>pe,asMilliseconds:()=>b,asRetryCount:()=>h,default:()=>N,errorRule:()=>re,orThrow:()=>de,run:()=>ce,runOrThrow:()=>le,tryo:()=>N});module.exports=ge(Ue);var f=class extends Error{constructor(t,n){var o,s;super(t);d(this,"cause");d(this,"title");d(this,"meta");d(this,"status");d(this,"raw");d(this,"path");d(this,"timestamp");d(this,"retryable");this.timestamp=Date.now(),this.retryable=(o=n.retryable)!=null?o:!0,this.name=this.constructor.name,this.cause=n.cause,this.title=n.title,this.meta=(s=n.meta)!=null?s:{},this.status=n.status,this.raw=n.raw,this.path=n.path,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}is(t){return this.code===t}withMeta(t){return Object.assign(this,{meta:t})}withStatus(t){return Object.assign(this,{status:t})}withCause(t){return Object.assign(this,{cause:t})}withPath(t){return this.path=t,this}withRaw(t){return Object.assign(this,{raw:t})}withRetryable(t){return this.retryable=t,this}toJSON(){return{name:this.name,code:this.code,title:this.title,message:this.message,timestamp:this.timestamp,retryable:this.retryable,cause:this.cause,raw:this.raw,path:this.path,stack:this.stack}}},B=class extends f{constructor(t,n){super(`Operation timed out after ${t}ms`,{cause:n,retryable:!0});d(this,"code","TIMEOUT")}};var _=class extends f{constructor(t,n){super(`Circuit breaker is open, reset after ${t}ms`,{cause:n,retryable:!1});d(this,"code","CIRCUIT_OPEN")}};var U=class extends f{constructor(t,n){super(t,{cause:n});d(this,"code","UNKNOWN")}};var b=e=>{if(e<0||!Number.isFinite(e))throw new Error(`Invalid milliseconds: must be a non-negative finite number, got ${e}`);return e},h=e=>{if(e<0||!Number.isInteger(e))throw new Error(`Invalid retry count: must be a non-negative integer, got ${e}`);return e},W=e=>{if(e<1||!Number.isInteger(e))throw new Error(`Invalid concurrency limit: must be a positive integer, got ${e}`);return e},X=e=>{if(e<0||e>100||!Number.isFinite(e))throw new Error(`Invalid percentage: must be between 0 and 100, got ${e}`);return e};var L=class{constructor(r){d(this,"state");d(this,"config");this.config={failureThreshold:h(r.failureThreshold),resetTimeout:b(r.resetTimeout),halfOpenRequests:h(r.halfOpenRequests),shouldCountAsFailure:r.shouldCountAsFailure},this.state={state:"closed",failureCount:0,halfOpenCount:0}}async canExecute(){if(this.updateStateIfNeeded(),this.state.state==="open")return!1;if(this.state.state==="half-open"){if(this.state.halfOpenCount>=this.config.halfOpenRequests)return!1;this.state={...this.state,halfOpenCount:this.state.halfOpenCount+1}}return!0}async recordSuccess(){switch(this.state.state){case"closed":this.state={...this.state,failureCount:0};break;case"half-open":this.state={state:"closed",failureCount:0,halfOpenCount:0};break;case"open":break}}async recordFailure(r){var o,s,a;if(!((a=(s=(o=this.config).shouldCountAsFailure)==null?void 0:s.call(o,r))!=null?a:!0))return;let n=new Date;switch(this.state.state){case"closed":{let i=this.state.failureCount+1;i>=this.config.failureThreshold?this.state={state:"open",failureCount:i,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)}:this.state={...this.state,failureCount:i,lastFailureTime:n};break}case"half-open":this.state={state:"open",failureCount:this.state.failureCount+1,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break;case"open":this.state={...this.state,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break}}getState(){return this.updateStateIfNeeded(),{...this.state,canExecute:this.state.state!=="open"}}createOpenError(){let r=this.state.nextAttemptTime?b(Math.max(0,this.state.nextAttemptTime.getTime()-Date.now())):this.config.resetTimeout;return new _(r)}forceState(r){this.state={state:r,failureCount:0,halfOpenCount:0}}reset(){this.state={state:"closed",failureCount:0,halfOpenCount:0}}updateStateIfNeeded(){this.state.state==="open"&&this.state.nextAttemptTime&&new Date>=this.state.nextAttemptTime&&(this.state={...this.state,state:"half-open",halfOpenCount:0})}};var Z=(e,r)=>t=>{for(let n of e){let o=n(t);if(o!==null)return o}return r(t)},ee=e=>r=>r instanceof f?r:r instanceof Error?new e(r.message,r):typeof r=="string"?new e(r):new e("Unknown error occurred",r);var ke=e=>{let t=e.toString().match(/\bcode\s*:\s*['"`]([^'"`]+)['"`]/);return t==null?void 0:t[1]},Oe=e=>{if(typeof e!="object"||e===null)return!1;let r=e;return typeof r.status=="number"||typeof r.statusCode=="number"},Ae=e=>{if(typeof e!="object"||e===null)return!1;let r=e;return typeof r.code=="string"&&r.code.length>0},Se=e=>{var r;if(e instanceof Error){let t=e.message.toLowerCase();if(e.name==="TypeError"&&(t.includes("fetch")&&t.includes("failed")||t.includes("network"))||t.includes("fetch")&&t.includes("failed")||t.includes("network"))return!0}if(Ae(e)){let t=((r=e.code)!=null?r:"").toUpperCase();return t==="ECONNRESET"||t==="ECONNREFUSED"||t==="ETIMEDOUT"||t==="ENOTFOUND"||t==="EAI_AGAIN"}return!1},Ne=e=>typeof e=="object"&&e!==null,z=class{constructor(r){this.predicate=r}toCode(r){return new K(this.predicate,r)}toError(r){let t=o=>{var c;if(!this.predicate(o))return null;let s=r(o),a=s.code,i=Object.hasOwn(s,"cause")?s.cause:o,l=(c=s.meta)!=null?c:{};class u extends f{constructor(){let m=Object.hasOwn(s,"raw")?s.raw:o;super(s.message,{title:s.title,cause:i,meta:l,status:s.status,retryable:s.retryable,raw:m,path:s.path});d(this,"code",a)}}return new u},n=ke(r);return n&&(t.__tryoCode=n),t}};function Me(e,r){let t=new z(s=>s instanceof e);if(r)return t.toError(r);let o=s=>{if(!(s instanceof e))return null;if(s instanceof f)return s;let a=s,i=typeof a.code=="string"&&a.code.length>0?a.code:"UNKNOWN",l=Object.hasOwn(a,"cause"),u=Object.hasOwn(a,"raw");class c extends f{constructor(){super(a.message||i,{title:typeof a.title=="string"?a.title:void 0,cause:l?a.cause:s,meta:Ne(a.meta)?a.meta:{},status:typeof a.status=="number"?a.status:void 0,retryable:typeof a.retryable=="boolean"?a.retryable:void 0,raw:u?a.raw:s,path:typeof a.path=="string"?a.path:void 0});d(this,"code",i)}}return new c};return o.toCode=t.toCode.bind(t),o.toError=t.toError.bind(t),o}var K=class{constructor(r,t){this.predicate=r;this.errorCode=t}with(r){let t=n=>{var u;if(!this.predicate(n))return null;let o=r(n),s=Object.hasOwn(o,"cause")?o.cause:n,a=(u=o.meta)!=null?u:{},i=this.errorCode;class l extends f{constructor(){let m=Object.hasOwn(o,"raw")?o.raw:n;super(o.message,{title:o.title,cause:s,meta:a,status:o.status,retryable:o.retryable,raw:m,path:o.path});d(this,"code",i)}}return new l};return t.__tryoCode=this.errorCode,t}},R={when:e=>new z(e),instance:Me},x={typed:(e=>e instanceof f?e:null),abort:R.when(e=>e instanceof Error&&e.name==="AbortError").toCode("ABORTED").with(e=>({message:e.message||"Operation was aborted",cause:e,retryable:!1,raw:e})),timeout:R.when(e=>e instanceof Error&&e.name==="TimeoutError").toCode("TIMEOUT").with(e=>({message:e.message||"Operation timed out",cause:e,raw:e})),network:R.when(e=>Se(e)).toCode("NETWORK").with(e=>({message:(e instanceof Error,e.message||"Network error"),cause:e,raw:e})),http:R.when(e=>{var n;if(!Oe(e))return!1;let r=e,t=(n=r.status)!=null?n:r.statusCode;return typeof t=="number"&&t>=400}).toCode("HTTP").with(e=>{var n;let r=(n=e.status)!=null?n:e.statusCode,t=typeof r=="number"&&(r>=500||r===429);return{message:e.message||`HTTP ${r!=null?r:"error"} error`,cause:e,status:typeof r=="number"?r:void 0,retryable:t,raw:e}}),unknown:R.when(e=>e instanceof Error&&!(e instanceof f)).toCode("UNKNOWN").with(e=>({message:e.message||"Unknown error occurred",cause:e,raw:e}))};var Ie=[x.typed,x.abort,x.timeout,x.http,x.network,x.unknown];var re={when:e=>R.when(e),instance:R.instance},te=Ie;var ne={fixed:e=>({type:"fixed",delay:e}),exponential:(e,r=2,t)=>({type:"exponential",base:e,factor:r,maxDelay:t}),fibonacci:(e,r)=>({type:"fibonacci",base:e,maxDelay:r}),custom:e=>({type:"custom",calculate:e})},oe=(e,r,t)=>{switch(e.type){case"fixed":return e.delay;case"exponential":{let n=e.base*e.factor**(Number(r)-1);return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"fibonacci":{let n=e.base*ve(Number(r));return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"custom":return e.calculate(r,t);default:return e}},ve=e=>{if(e<=1)return 1;let r=1,t=1;for(let n=2;n<=e;n++){let o=r+t;r=t,t=o}return t},se=e=>{switch(e.type){case"fixed":{if(e.delay<0)throw new Error("Fixed delay must be non-negative");break}case"exponential":if(e.base<=0)throw new Error("Exponential base delay must be positive");if(e.factor<=1)throw new Error("Exponential factor must be greater than 1");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Exponential max delay must be positive");break;case"fibonacci":if(e.base<=0)throw new Error("Fibonacci base delay must be positive");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Fibonacci max delay must be positive");break;case"custom":break;default:{let r=e;throw new Error(`Unknown strategy type: ${r}`)}}};var ae=(e,r)=>new Promise((t,n)=>{if(r!=null&&r.aborted){n(new DOMException("Aborted","AbortError"));return}let o=i=>{r&&i&&r.removeEventListener("abort",i)},s,a=()=>{s&&clearTimeout(s),o(a),n(new DOMException("Aborted","AbortError"))};s=setTimeout(()=>{o(a),t()},e),r==null||r.addEventListener("abort",a,{once:!0})}),ie=(e,r,t,n)=>new Promise((o,s)=>{if(t!=null&&t.aborted){s(new DOMException("Aborted","AbortError"));return}let a=!1,i=setTimeout(()=>{var c;a=!0,u(),s((c=n==null?void 0:n())!=null?c:new Error(`Operation timed out after ${r}ms`))},r),l=()=>{a||(a=!0,u(),s(new DOMException("Aborted","AbortError")))},u=()=>{clearTimeout(i),t==null||t.removeEventListener("abort",l)};t==null||t.addEventListener("abort",l,{once:!0}),e.then(c=>{a||(a=!0,u(),o(c))},c=>{a||(a=!0,u(),s(c))})});var De=e=>{var a,i,l;if(e.toError)return e.toError;let r=(a=e.rulesMode)!=null?a:"extend",t=(i=e.rules)!=null?i:[];Pe(t);let n=te,o=(l=e.fallback)!=null?l:(u=>ee(U)(u)),s=r==="replace"?t:[...t,...n];return Z(s,o)},Pe=e=>{let r=new Set;for(let t of e){let n=t.__tryoCode;if(n){if(r.has(n))throw new Error(`Duplicate rule code detected: ${n}`);r.add(n)}}},Fe=e=>{if(e)switch(e.type){case"none":return;case"full":case"equal":X(e.ratio);return;case"custom":return;default:{let r=e;throw new Error(`Unsupported jitter configuration: ${r}`)}}},V=e=>{let r=e;return r.timeout!==void 0&&(r={...r,timeout:Number(b(r.timeout))}),r.concurrency!==void 0&&(r={...r,concurrency:Number.isFinite(r.concurrency)?Number(W(r.concurrency)):r.concurrency}),r.retry&&(se(r.retry.strategy),Fe(r.retry.jitter),r={...r,retry:{...r.retry,maxRetries:Number(h(r.retry.maxRetries))}}),r},J=class e{constructor(r={}){d(this,"circuitBreaker");d(this,"config");d(this,"lastCircuitState");let{rules:t,rulesMode:n,fallback:o,toError:s,mapError:a,...i}=r,l=De(r),u={...i,errorHandling:{normalizer:l,mapError:a}};this.config=V(u),u.circuitBreaker&&(this.circuitBreaker=new L(u.circuitBreaker),this.lastCircuitState=this.circuitBreaker.getState().state)}async run(r,t={}){var s,a,i,l;let n=V({...this.config,...t});if(this.circuitBreaker){let u=(s=this.lastCircuitState)!=null?s:this.circuitBreaker.getState().state,c=await this.circuitBreaker.canExecute(),y=this.circuitBreaker.getState().state;if(u!==y)try{(a=n.onCircuitStateChange)==null||a.call(n,u,y)}catch{}if(this.lastCircuitState=y,!c)return{type:"failure",ok:!1,data:null,error:this.circuitBreaker.createOpenError(),metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,retryHistory:[]}}}let o=await Be(r,n);if(this.circuitBreaker){let u=(i=this.lastCircuitState)!=null?i:this.circuitBreaker.getState().state;o.ok?await this.circuitBreaker.recordSuccess():await this.circuitBreaker.recordFailure(o.error);let c=this.circuitBreaker.getState().state;if(u!==c)try{(l=n.onCircuitStateChange)==null||l.call(n,u,c)}catch{}this.lastCircuitState=c}return o}async runOrThrow(r,t={}){return this.orThrow(r,t)}async orThrow(r,t={}){let n=await this.run(r,t);if(n.ok)return n.data;throw n.error}async all(r,t={}){var c;let n=V({...this.config,...t}),o=(c=n.concurrency)!=null?c:Number.POSITIVE_INFINITY,s=Number.isFinite(o)?Number(W(o)):Number.POSITIVE_INFINITY;if(s===Number.POSITIVE_INFINITY)return Promise.all(r.map(y=>this.run(y,n)));let a=new Array(r.length),i=0,l=async()=>{var y;for(;i<r.length&&!((y=n.signal)!=null&&y.aborted);){let T=i++;if(T>=r.length)break;let m=r[T];m&&(a[T]=await this.run(m,n))}},u=Array.from({length:Math.min(s,r.length)},()=>l());await Promise.all(u);for(let y=0;y<r.length;y++)if(!(y in a)){let T=r[y];T&&(a[y]=await this.run(T,n))}return a}async allOrThrow(r,t={}){return(await this.all(r,t)).map(o=>{if(!o.ok)throw o.error;return o.data})}partitionAll(r){let t=[],n=[],o=[],s=[],a=[];for(let i of r){if(i.type==="success"){t.push(i);continue}switch(n.push(i),i.type){case"failure":o.push(i);break;case"aborted":s.push(i);break;case"timeout":a.push(i);break}}return{ok:t,errors:n,failure:o,aborted:s,timeout:a}}getCircuitBreakerState(){var r;return(r=this.circuitBreaker)==null?void 0:r.getState()}resetCircuitBreaker(){var r;(r=this.circuitBreaker)==null||r.reset()}getConfig(){return{...this.config}}withConfig(r){var l,u;let{errorHandling:t,...n}=this.config,{errorHandling:o,...s}=r,a=(l=o==null?void 0:o.normalizer)!=null?l:t.normalizer,i=(u=o==null?void 0:o.mapError)!=null?u:t.mapError;return new e({...n,...s,toError:a,mapError:i})}};function N(e={}){let r=new J(e);return{run:(t,n)=>r.run(t,n),orThrow:(t,n)=>r.orThrow(t,n),runOrThrow:(t,n)=>r.runOrThrow(t,n),all:(t,n)=>r.all(t,n),allOrThrow:(t,n)=>r.allOrThrow(t,n),partitionAll:t=>r.partitionAll(t),withConfig:t=>r.withConfig(t)}}async function Be(e,r){let{signal:t,ignoreAbort:n=!0,timeout:o,retry:s,errorHandling:a,logger:i,onSuccess:l,onError:u,onFinally:c,onAbort:y,onRetry:T}=r,m=(C,...p)=>{try{C==null||C(...p)}catch{}},I,k=0,g=[],H=Date.now(),{signal:v,cleanup:me}=ue(t),O=C=>({totalAttempts:k,totalRetries:k>0?Number(k)-1:0,totalDuration:Date.now()-H,lastError:C,retryHistory:g});try{if(v.aborted){m(y,v);let p=a.normalizer(new DOMException("Aborted","AbortError")),w=a.mapError?a.mapError(p):p;return{type:"aborted",ok:!1,data:null,error:w,metrics:O(w)}}let C=async()=>{var D,A,j;let p=1,w=h((D=s==null?void 0:s.maxRetries)!=null?D:0);for(;;){k=p;let Y=new AbortController,{signal:$,cleanup:fe}=ue(v,Y.signal);try{let P=Promise.resolve(e({signal:$})),S=o?await ie(P,o,$,()=>(Y.abort(),new B(b(o)))):await P;return m(l,S,O()),m(i==null?void 0:i.info,`Task succeeded on attempt ${p}`),S}catch(P){let S=a.normalizer(P),E=a.mapError?a.mapError(S):S;if(I=E,E.code==="ABORTED"&&m(y,$),n&&E.code==="ABORTED"||(m(u,E,O(E)),m(i==null?void 0:i.error,`Task failed on attempt ${p}`,E)),E.code==="ABORTED"||E.retryable===!1)throw E;if(p<=Number(w)){let G=s==null?void 0:s.shouldRetry,Ee={totalAttempts:Number(k),elapsedTime:Date.now()-H,startTime:new Date(H),lastDelay:(A=g[g.length-1])!=null&&A.delay?Number((j=g[g.length-1])==null?void 0:j.delay):void 0};if(!G||G(p,E,Ee)){let Te=s?oe(s.strategy,p,E):0,q=_e(Te,s==null?void 0:s.jitter),Q=b(q);g.push({attempt:p,error:E,delay:Q,timestamp:new Date}),m(T,p,E,q),m(i==null?void 0:i.info,`Retrying in ${q}ms (attempt ${p+1})`),p+=1,await ae(Q,v);continue}}throw E}finally{fe()}}};try{let p=await C(),w=O();return m(c,w),{type:"success",ok:!0,data:p,error:null,metrics:w}}catch(p){let w=I!=null?I:a.normalizer(p),D=w.code==="TIMEOUT"?"timeout":w.code==="ABORTED"?"aborted":"failure",A=O(w);return m(c,A),{type:D,ok:!1,data:null,error:w,metrics:A}}}finally{me()}}function ue(...e){let r=new AbortController,t=e.filter(o=>o!==void 0);if(t.length===0)return{signal:r.signal,cleanup:()=>{}};if(t.some(o=>o.aborted))return r.abort(),{signal:r.signal,cleanup:()=>{}};let n=[];for(let o of t){let s=()=>r.abort();o.addEventListener("abort",s,{once:!0}),n.push({signal:o,abort:s})}return{signal:r.signal,cleanup:()=>{for(let o of n)o.signal.removeEventListener("abort",o.abort)}}}function _e(e,r){if(!r||r.type==="none"||e<=0)return e;switch(r.type){case"full":{let t=Number(r.ratio)/100,n=Math.max(0,Number(e)*(1-t)),o=Number(e);return n+Math.random()*(o-n)}case"equal":{let t=Number(r.ratio)/100,n=Number(e)*t/2;return Number(e)-n+Math.random()*n}case"custom":return r.calculate(e);default:return r}}var M=N(),ce=M.run,le=M.runOrThrow,de=M.orThrow,ye=M.all,pe=M.allOrThrow;0&&(module.exports={RetryStrategies,TypedError,all,allOrThrow,asMilliseconds,asRetryCount,errorRule,orThrow,run,runOrThrow,tryo});
|
|
1
|
+
"use strict";var F=Object.defineProperty;var he=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var we=Object.prototype.hasOwnProperty;var Re=(e,t,r)=>t in e?F(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var Ce=(e,t)=>{for(var r in t)F(e,r,{get:t[r],enumerable:!0})},xe=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of be(t))!we.call(e,o)&&o!==r&&F(e,o,{get:()=>t[o],enumerable:!(n=he(t,o))||n.enumerable});return e};var ge=e=>xe(F({},"__esModule",{value:!0}),e);var d=(e,t,r)=>Re(e,typeof t!="symbol"?t+"":t,r);var Ue={};Ce(Ue,{RetryStrategies:()=>ne,TypedError:()=>f,all:()=>ye,allOrThrow:()=>pe,asMilliseconds:()=>b,asRetryCount:()=>w,default:()=>M,errorRule:()=>te,orThrow:()=>de,run:()=>ce,runOrThrow:()=>le,tryo:()=>M});module.exports=ge(Ue);var f=class extends Error{constructor(r,n){var o,s;super(r);d(this,"cause");d(this,"title");d(this,"meta");d(this,"status");d(this,"raw");d(this,"path");d(this,"timestamp");d(this,"retryable");this.timestamp=Date.now(),this.retryable=(o=n.retryable)!=null?o:!0,this.name=this.constructor.name,this.cause=n.cause,this.title=n.title,this.meta=(s=n.meta)!=null?s:{},this.status=n.status,this.raw=n.raw,this.path=n.path,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}is(r){return this.code===r}withMeta(r){return this.meta=r,this}withStatus(r){return this.status=r,this}withCause(r){return this.cause=r,this}withPath(r){return this.path=r,this}withRaw(r){return this.raw=r,this}withRetryable(r){return this.retryable=r,this}toJSON(){return{name:this.name,code:this.code,title:this.title,message:this.message,meta:this.meta,status:this.status,timestamp:this.timestamp,retryable:this.retryable,cause:this.cause,raw:this.raw,path:this.path,stack:this.stack}}},B=class extends f{constructor(r,n){super(`Operation timed out after ${r}ms`,{cause:n,retryable:!0});d(this,"code","TIMEOUT")}};var _=class extends f{constructor(r,n){super(`Circuit breaker is open, reset after ${r}ms`,{cause:n,retryable:!1});d(this,"code","CIRCUIT_OPEN")}};var U=class extends f{constructor(r,n){super(r,{cause:n});d(this,"code","UNKNOWN")}};var b=e=>{if(e<0||!Number.isFinite(e))throw new Error(`Invalid milliseconds: must be a non-negative finite number, got ${e}`);return e},w=e=>{if(e<0||!Number.isInteger(e))throw new Error(`Invalid retry count: must be a non-negative integer, got ${e}`);return e},W=e=>{if(e<1||!Number.isInteger(e))throw new Error(`Invalid concurrency limit: must be a positive integer, got ${e}`);return e},X=e=>{if(e<0||e>100||!Number.isFinite(e))throw new Error(`Invalid percentage: must be between 0 and 100, got ${e}`);return e};var L=class{constructor(t){d(this,"state");d(this,"config");this.config={failureThreshold:w(t.failureThreshold),resetTimeout:b(t.resetTimeout),halfOpenRequests:w(t.halfOpenRequests),shouldCountAsFailure:t.shouldCountAsFailure},this.state={state:"closed",failureCount:0,halfOpenCount:0}}async canExecute(){if(this.updateStateIfNeeded(),this.state.state==="open")return!1;if(this.state.state==="half-open"){if(this.state.halfOpenCount>=this.config.halfOpenRequests)return!1;this.state={...this.state,halfOpenCount:this.state.halfOpenCount+1}}return!0}async recordSuccess(){switch(this.state.state){case"closed":this.state={...this.state,failureCount:0};break;case"half-open":this.state={state:"closed",failureCount:0,halfOpenCount:0};break;case"open":break}}async recordFailure(t){var o,s,a;if(!((a=(s=(o=this.config).shouldCountAsFailure)==null?void 0:s.call(o,t))!=null?a:!0))return;let n=new Date;switch(this.state.state){case"closed":{let i=this.state.failureCount+1;i>=this.config.failureThreshold?this.state={state:"open",failureCount:i,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)}:this.state={...this.state,failureCount:i,lastFailureTime:n};break}case"half-open":this.state={state:"open",failureCount:this.state.failureCount+1,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break;case"open":this.state={...this.state,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break}}getState(){return this.updateStateIfNeeded(),{...this.state,canExecute:this.state.state!=="open"}}createOpenError(){let t=this.state.nextAttemptTime?b(Math.max(0,this.state.nextAttemptTime.getTime()-Date.now())):this.config.resetTimeout;return new _(t)}forceState(t){this.state={state:t,failureCount:0,halfOpenCount:0}}reset(){this.state={state:"closed",failureCount:0,halfOpenCount:0}}updateStateIfNeeded(){this.state.state==="open"&&this.state.nextAttemptTime&&new Date>=this.state.nextAttemptTime&&(this.state={...this.state,state:"half-open",halfOpenCount:0})}};var Z=(e,t)=>r=>{for(let n of e){let o=n(r);if(o!==null)return o}return t(r)},ee=e=>t=>t instanceof f?t:t instanceof Error?new e(t.message,t):typeof t=="string"?new e(t):new e("Unknown error occurred",t);var ke=e=>{let r=e.toString().match(/\bcode\s*:\s*['"`]([^'"`]+)['"`]/);return r==null?void 0:r[1]},Oe=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.status=="number"||typeof t.statusCode=="number"},Ae=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.code=="string"&&t.code.length>0},Se=e=>{var t;if(e instanceof Error){let r=e.message.toLowerCase();if(e.name==="TypeError"&&(r.includes("fetch")&&r.includes("failed")||r.includes("network"))||r.includes("fetch")&&r.includes("failed")||r.includes("network"))return!0}if(Ae(e)){let r=((t=e.code)!=null?t:"").toUpperCase();return r==="ECONNRESET"||r==="ECONNREFUSED"||r==="ETIMEDOUT"||r==="ENOTFOUND"||r==="EAI_AGAIN"}return!1},Me=e=>typeof e=="object"&&e!==null,z=class{constructor(t){this.predicate=t}toCode(t){return new K(this.predicate,t)}toError(t){let r=o=>{var c;if(!this.predicate(o))return null;let s=t(o),a=s.code,i=Object.hasOwn(s,"cause")?s.cause:o,l=(c=s.meta)!=null?c:{};class u extends f{constructor(){let m=Object.hasOwn(s,"raw")?s.raw:o;super(s.message,{title:s.title,cause:i,meta:l,status:s.status,retryable:s.retryable,raw:m,path:s.path});d(this,"code",a)}}return new u},n=ke(t);return n&&(r.__tryoCode=n),r}};function Ne(e,t){let r=new z(s=>s instanceof e);if(t)return r.toError(t);let o=s=>{if(!(s instanceof e))return null;if(s instanceof f)return s;let a=s,i=typeof a.code=="string"&&a.code.length>0?a.code:"UNKNOWN",l=Object.hasOwn(a,"cause"),u=Object.hasOwn(a,"raw");class c extends f{constructor(){super(a.message||i,{title:typeof a.title=="string"?a.title:void 0,cause:l?a.cause:s,meta:Me(a.meta)?a.meta:{},status:typeof a.status=="number"?a.status:void 0,retryable:typeof a.retryable=="boolean"?a.retryable:void 0,raw:u?a.raw:s,path:typeof a.path=="string"?a.path:void 0});d(this,"code",i)}}return new c};return o.toCode=r.toCode.bind(r),o.toError=r.toError.bind(r),o}var K=class{constructor(t,r){this.predicate=t;this.errorCode=r}with(t){let r=n=>{var u;if(!this.predicate(n))return null;let o=t(n),s=Object.hasOwn(o,"cause")?o.cause:n,a=(u=o.meta)!=null?u:{},i=this.errorCode;class l extends f{constructor(){let m=Object.hasOwn(o,"raw")?o.raw:n;super(o.message,{title:o.title,cause:s,meta:a,status:o.status,retryable:o.retryable,raw:m,path:o.path});d(this,"code",i)}}return new l};return r.__tryoCode=this.errorCode,r}},R={when:e=>new z(e),instance:Ne},x={typed:(e=>e instanceof f?e:null),abort:R.when(e=>e instanceof Error&&e.name==="AbortError").toCode("ABORTED").with(e=>({message:e.message||"Operation was aborted",cause:e,retryable:!1,raw:e})),timeout:R.when(e=>e instanceof Error&&e.name==="TimeoutError").toCode("TIMEOUT").with(e=>({message:e.message||"Operation timed out",cause:e,raw:e})),network:R.when(e=>Se(e)).toCode("NETWORK").with(e=>({message:(e instanceof Error,e.message||"Network error"),cause:e,raw:e})),http:R.when(e=>{var n;if(!Oe(e))return!1;let t=e,r=(n=t.status)!=null?n:t.statusCode;return typeof r=="number"&&r>=400}).toCode("HTTP").with(e=>{var n;let t=(n=e.status)!=null?n:e.statusCode,r=typeof t=="number"&&(t>=500||t===429);return{message:e.message||`HTTP ${t!=null?t:"error"} error`,cause:e,status:typeof t=="number"?t:void 0,retryable:r,raw:e}}),unknown:R.when(e=>e instanceof Error&&!(e instanceof f)).toCode("UNKNOWN").with(e=>({message:e.message||"Unknown error occurred",cause:e,raw:e}))};var ve=[x.typed,x.abort,x.timeout,x.http,x.network,x.unknown];var te={when:e=>R.when(e),instance:R.instance},re=ve;var ne={fixed:e=>({type:"fixed",delay:e}),exponential:(e,t=2,r)=>({type:"exponential",base:e,factor:t,maxDelay:r}),fibonacci:(e,t)=>({type:"fibonacci",base:e,maxDelay:t}),custom:e=>({type:"custom",calculate:e})},oe=(e,t,r)=>{switch(e.type){case"fixed":return e.delay;case"exponential":{let n=e.base*e.factor**(Number(t)-1);return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"fibonacci":{let n=e.base*Ie(Number(t));return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"custom":return e.calculate(t,r);default:return e}},Ie=e=>{if(e<=1)return 1;let t=1,r=1;for(let n=2;n<=e;n++){let o=t+r;t=r,r=o}return r},se=e=>{switch(e.type){case"fixed":{if(e.delay<0)throw new Error("Fixed delay must be non-negative");break}case"exponential":if(e.base<=0)throw new Error("Exponential base delay must be positive");if(e.factor<=1)throw new Error("Exponential factor must be greater than 1");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Exponential max delay must be positive");break;case"fibonacci":if(e.base<=0)throw new Error("Fibonacci base delay must be positive");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Fibonacci max delay must be positive");break;case"custom":break;default:{let t=e;throw new Error(`Unknown strategy type: ${t}`)}}};var ae=(e,t)=>new Promise((r,n)=>{if(t!=null&&t.aborted){n(new DOMException("Aborted","AbortError"));return}let o=i=>{t&&i&&t.removeEventListener("abort",i)},s,a=()=>{s&&clearTimeout(s),o(a),n(new DOMException("Aborted","AbortError"))};s=setTimeout(()=>{o(a),r()},e),t==null||t.addEventListener("abort",a,{once:!0})}),ie=(e,t,r,n)=>new Promise((o,s)=>{if(r!=null&&r.aborted){s(new DOMException("Aborted","AbortError"));return}let a=!1,i=setTimeout(()=>{var c;a=!0,u(),s((c=n==null?void 0:n())!=null?c:new Error(`Operation timed out after ${t}ms`))},t),l=()=>{a||(a=!0,u(),s(new DOMException("Aborted","AbortError")))},u=()=>{clearTimeout(i),r==null||r.removeEventListener("abort",l)};r==null||r.addEventListener("abort",l,{once:!0}),e.then(c=>{a||(a=!0,u(),o(c))},c=>{a||(a=!0,u(),s(c))})});var De=e=>{var a,i,l;if(e.toError)return e.toError;let t=(a=e.rulesMode)!=null?a:"extend",r=(i=e.rules)!=null?i:[];Pe(r);let n=re,o=(l=e.fallback)!=null?l:(u=>ee(U)(u)),s=t==="replace"?r:[...r,...n];return Z(s,o)},Pe=e=>{let t=new Set;for(let r of e){let n=r.__tryoCode;if(n){if(t.has(n))throw new Error(`Duplicate rule code detected: ${n}`);t.add(n)}}},Fe=e=>{if(e)switch(e.type){case"none":return;case"full":case"equal":X(e.ratio);return;case"custom":return;default:{let t=e;throw new Error(`Unsupported jitter configuration: ${t}`)}}},V=e=>{let t=e;return t.timeout!==void 0&&(t={...t,timeout:Number(b(t.timeout))}),t.concurrency!==void 0&&(t={...t,concurrency:Number.isFinite(t.concurrency)?Number(W(t.concurrency)):t.concurrency}),t.retry&&(se(t.retry.strategy),Fe(t.retry.jitter),t={...t,retry:{...t.retry,maxRetries:Number(w(t.retry.maxRetries))}}),t},J=class e{constructor(t={}){d(this,"circuitBreaker");d(this,"config");d(this,"lastCircuitState");let{rules:r,rulesMode:n,fallback:o,toError:s,mapError:a,...i}=t,l=De(t),u={...i,errorHandling:{normalizer:l,mapError:a}};this.config=V(u),u.circuitBreaker&&(this.circuitBreaker=new L(u.circuitBreaker),this.lastCircuitState=this.circuitBreaker.getState().state)}async run(t,r={}){var s,a,i,l;let n=V({...this.config,...r});if(this.circuitBreaker){let u=(s=this.lastCircuitState)!=null?s:this.circuitBreaker.getState().state,c=await this.circuitBreaker.canExecute(),y=this.circuitBreaker.getState().state;if(u!==y)try{(a=n.onCircuitStateChange)==null||a.call(n,u,y)}catch{}if(this.lastCircuitState=y,!c)return{type:"failure",ok:!1,data:null,error:this.circuitBreaker.createOpenError(),metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,retryHistory:[]}}}let o=await Be(t,n);if(this.circuitBreaker){let u=(i=this.lastCircuitState)!=null?i:this.circuitBreaker.getState().state;o.ok?await this.circuitBreaker.recordSuccess():await this.circuitBreaker.recordFailure(o.error);let c=this.circuitBreaker.getState().state;if(u!==c)try{(l=n.onCircuitStateChange)==null||l.call(n,u,c)}catch{}this.lastCircuitState=c}return o}async runOrThrow(t,r={}){return this.orThrow(t,r)}async orThrow(t,r={}){let n=await this.run(t,r);if(n.ok)return n.data;throw n.error}async all(t,r={}){var c;let n=V({...this.config,...r}),o=(c=n.concurrency)!=null?c:Number.POSITIVE_INFINITY,s=Number.isFinite(o)?Number(W(o)):Number.POSITIVE_INFINITY;if(s===Number.POSITIVE_INFINITY)return Promise.all(t.map(y=>this.run(y,n)));let a=new Array(t.length),i=0,l=async()=>{var y;for(;i<t.length&&!((y=n.signal)!=null&&y.aborted);){let T=i++;if(T>=t.length)break;let m=t[T];m&&(a[T]=await this.run(m,n))}},u=Array.from({length:Math.min(s,t.length)},()=>l());await Promise.all(u);for(let y=0;y<t.length;y++)if(!(y in a)){let T=t[y];T&&(a[y]=await this.run(T,n))}return a}async allOrThrow(t,r={}){return(await this.all(t,r)).map(o=>{if(!o.ok)throw o.error;return o.data})}partitionAll(t){let r=[],n=[],o=[],s=[],a=[];for(let i of t){if(i.type==="success"){r.push(i);continue}switch(n.push(i),i.type){case"failure":o.push(i);break;case"aborted":s.push(i);break;case"timeout":a.push(i);break}}return{ok:r,errors:n,failure:o,aborted:s,timeout:a}}getCircuitBreakerState(){var t;return(t=this.circuitBreaker)==null?void 0:t.getState()}resetCircuitBreaker(){var t;(t=this.circuitBreaker)==null||t.reset()}getConfig(){return{...this.config}}withConfig(t){var l,u;let{errorHandling:r,...n}=this.config,{errorHandling:o,...s}=t,a=(l=o==null?void 0:o.normalizer)!=null?l:r.normalizer,i=(u=o==null?void 0:o.mapError)!=null?u:r.mapError;return new e({...n,...s,toError:a,mapError:i})}};function M(e={}){let t=new J(e);return{run:(r,n)=>t.run(r,n),orThrow:(r,n)=>t.orThrow(r,n),runOrThrow:(r,n)=>t.runOrThrow(r,n),all:(r,n)=>t.all(r,n),allOrThrow:(r,n)=>t.allOrThrow(r,n),partitionAll:r=>t.partitionAll(r),withConfig:r=>t.withConfig(r)}}async function Be(e,t){let{signal:r,ignoreAbort:n=!0,timeout:o,retry:s,errorHandling:a,logger:i,onSuccess:l,onError:u,onFinally:c,onAbort:y,onRetry:T}=t,m=(C,...p)=>{try{C==null||C(...p)}catch{}},v,k=0,g=[],H=Date.now(),{signal:I,cleanup:me}=ue(r),O=C=>({totalAttempts:k,totalRetries:k>0?Number(k)-1:0,totalDuration:Date.now()-H,lastError:C,retryHistory:g});try{if(I.aborted){m(y,I);let p=a.normalizer(new DOMException("Aborted","AbortError")),h=a.mapError?a.mapError(p):p;return{type:"aborted",ok:!1,data:null,error:h,metrics:O(h)}}let C=async()=>{var D,A,Y;let p=1,h=w((D=s==null?void 0:s.maxRetries)!=null?D:0);for(;;){k=p;let j=new AbortController,{signal:$,cleanup:fe}=ue(I,j.signal);try{let P=Promise.resolve(e({signal:$})),S=o?await ie(P,o,$,()=>(j.abort(),new B(b(o)))):await P;return m(l,S,O()),m(i==null?void 0:i.info,`Task succeeded on attempt ${p}`),S}catch(P){let S=a.normalizer(P),E=a.mapError?a.mapError(S):S;if(v=E,E.code==="ABORTED"&&m(y,$),n&&E.code==="ABORTED"||(m(u,E,O(E)),m(i==null?void 0:i.error,`Task failed on attempt ${p}`,E)),E.code==="ABORTED"||E.retryable===!1)throw E;if(p<=Number(h)){let G=s==null?void 0:s.shouldRetry,Ee={totalAttempts:Number(k),elapsedTime:Date.now()-H,startTime:new Date(H),lastDelay:(A=g[g.length-1])!=null&&A.delay?Number((Y=g[g.length-1])==null?void 0:Y.delay):void 0};if(!G||G(p,E,Ee)){let Te=s?oe(s.strategy,p,E):0,q=_e(Te,s==null?void 0:s.jitter),Q=b(q);g.push({attempt:p,error:E,delay:Q,timestamp:new Date}),m(T,p,E,q),m(i==null?void 0:i.info,`Retrying in ${q}ms (attempt ${p+1})`),p+=1,await ae(Q,I);continue}}throw E}finally{fe()}}};try{let p=await C(),h=O();return m(c,h),{type:"success",ok:!0,data:p,error:null,metrics:h}}catch(p){let h=v!=null?v:a.normalizer(p),D=h.code==="TIMEOUT"?"timeout":h.code==="ABORTED"?"aborted":"failure",A=O(h);return m(c,A),{type:D,ok:!1,data:null,error:h,metrics:A}}}finally{me()}}function ue(...e){let t=new AbortController,r=e.filter(o=>o!==void 0);if(r.length===0)return{signal:t.signal,cleanup:()=>{}};if(r.some(o=>o.aborted))return t.abort(),{signal:t.signal,cleanup:()=>{}};let n=[];for(let o of r){let s=()=>t.abort();o.addEventListener("abort",s,{once:!0}),n.push({signal:o,abort:s})}return{signal:t.signal,cleanup:()=>{for(let o of n)o.signal.removeEventListener("abort",o.abort)}}}function _e(e,t){if(!t||t.type==="none"||e<=0)return e;switch(t.type){case"full":{let r=Number(t.ratio)/100,n=Math.max(0,Number(e)*(1-r)),o=Number(e);return n+Math.random()*(o-n)}case"equal":{let r=Number(t.ratio)/100,n=Number(e)*r/2;return Number(e)-n+Math.random()*n}case"custom":return t.calculate(e);default:return t}}var N=M(),ce=N.run,le=N.runOrThrow,de=N.orThrow,ye=N.all,pe=N.allOrThrow;0&&(module.exports={RetryStrategies,TypedError,all,allOrThrow,asMilliseconds,asRetryCount,errorRule,orThrow,run,runOrThrow,tryo});
|
package/dist/index.d.cts
CHANGED
|
@@ -16,16 +16,17 @@ declare const asRetryCount: (n: number) => RetryCount;
|
|
|
16
16
|
* Provides type-safe error handling with fluent API and metadata support
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
type DefaultErrorMeta = Record<string, unknown>;
|
|
20
|
+
declare abstract class TypedError<Code extends string = string, Meta extends object = DefaultErrorMeta, Raw = unknown> extends Error {
|
|
20
21
|
abstract readonly code: Code;
|
|
21
|
-
|
|
22
|
+
cause?: unknown;
|
|
22
23
|
readonly title?: string;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
meta: Meta;
|
|
25
|
+
status?: number;
|
|
26
|
+
raw?: Raw;
|
|
27
|
+
path?: string;
|
|
27
28
|
readonly timestamp: number;
|
|
28
|
-
|
|
29
|
+
retryable: boolean;
|
|
29
30
|
constructor(message: string, opts: {
|
|
30
31
|
title?: string;
|
|
31
32
|
cause?: unknown;
|
|
@@ -35,10 +36,10 @@ declare abstract class TypedError<Code extends string = string, Meta extends Rec
|
|
|
35
36
|
raw?: Raw;
|
|
36
37
|
path?: string;
|
|
37
38
|
});
|
|
38
|
-
is<C extends string>(code: C): this is TypedError<C> & {
|
|
39
|
+
is<C extends string>(code: C): this is TypedError<C, Meta, Raw> & {
|
|
39
40
|
code: C;
|
|
40
41
|
};
|
|
41
|
-
withMeta<const M>(meta: M): this & {
|
|
42
|
+
withMeta<const M extends object>(meta: M): this & {
|
|
42
43
|
meta: M;
|
|
43
44
|
};
|
|
44
45
|
withStatus(status: number): this & {
|
|
@@ -54,42 +55,42 @@ declare abstract class TypedError<Code extends string = string, Meta extends Rec
|
|
|
54
55
|
withRetryable(retryable: boolean): this;
|
|
55
56
|
toJSON(): Record<string, unknown>;
|
|
56
57
|
}
|
|
57
|
-
type AnyTypedError = TypedError
|
|
58
|
-
declare class TimeoutError extends TypedError<'TIMEOUT'
|
|
58
|
+
type AnyTypedError = TypedError;
|
|
59
|
+
declare class TimeoutError extends TypedError<'TIMEOUT'> {
|
|
59
60
|
readonly code: "TIMEOUT";
|
|
60
61
|
constructor(timeout: Milliseconds, cause?: unknown);
|
|
61
62
|
}
|
|
62
|
-
declare class AbortedError extends TypedError<'ABORTED'
|
|
63
|
+
declare class AbortedError extends TypedError<'ABORTED'> {
|
|
63
64
|
readonly code: "ABORTED";
|
|
64
65
|
constructor(reason?: string, cause?: unknown);
|
|
65
66
|
}
|
|
66
|
-
declare class CircuitOpenError extends TypedError<'CIRCUIT_OPEN'
|
|
67
|
+
declare class CircuitOpenError extends TypedError<'CIRCUIT_OPEN'> {
|
|
67
68
|
readonly code: "CIRCUIT_OPEN";
|
|
68
69
|
constructor(resetAfter: Milliseconds, cause?: unknown);
|
|
69
70
|
}
|
|
70
|
-
type ValidationMeta =
|
|
71
|
+
type ValidationMeta = {
|
|
71
72
|
validationErrors: unknown[];
|
|
72
73
|
};
|
|
73
|
-
declare class ValidationError extends TypedError<'VALIDATION', ValidationMeta
|
|
74
|
+
declare class ValidationError extends TypedError<'VALIDATION', ValidationMeta> {
|
|
74
75
|
readonly validationErrors: unknown[];
|
|
75
76
|
readonly code: "VALIDATION";
|
|
76
77
|
constructor(message: string, validationErrors: unknown[], cause?: unknown);
|
|
77
78
|
}
|
|
78
|
-
declare class NetworkError extends TypedError<'NETWORK'
|
|
79
|
+
declare class NetworkError extends TypedError<'NETWORK'> {
|
|
79
80
|
readonly statusCode?: number | undefined;
|
|
80
81
|
readonly code: "NETWORK";
|
|
81
82
|
constructor(message: string, statusCode?: number | undefined, cause?: unknown);
|
|
82
83
|
}
|
|
83
|
-
type HttpMeta =
|
|
84
|
+
type HttpMeta = {
|
|
84
85
|
response?: unknown;
|
|
85
86
|
};
|
|
86
|
-
declare class HttpError extends TypedError<'HTTP', HttpMeta
|
|
87
|
+
declare class HttpError extends TypedError<'HTTP', HttpMeta> {
|
|
87
88
|
readonly status: number;
|
|
88
89
|
readonly response?: unknown | undefined;
|
|
89
90
|
readonly code: "HTTP";
|
|
90
91
|
constructor(message: string, status: number, response?: unknown | undefined, cause?: unknown);
|
|
91
92
|
}
|
|
92
|
-
declare class UnknownError extends TypedError<'UNKNOWN'
|
|
93
|
+
declare class UnknownError extends TypedError<'UNKNOWN'> {
|
|
93
94
|
readonly code: "UNKNOWN";
|
|
94
95
|
constructor(message: string, cause?: unknown);
|
|
95
96
|
}
|
|
@@ -408,18 +409,24 @@ interface MapperResponse {
|
|
|
408
409
|
path?: string;
|
|
409
410
|
}
|
|
410
411
|
type Strict<T, Shape> = T & Record<Exclude<keyof T, keyof Shape>, never>;
|
|
411
|
-
type
|
|
412
|
+
type ResolvedMeta<TMeta> = TMeta extends Record<string, unknown> ? TMeta : Record<string, unknown>;
|
|
413
|
+
type ResolvedRaw<Out extends {
|
|
414
|
+
raw?: unknown;
|
|
415
|
+
}> = Out extends {
|
|
416
|
+
raw: infer TRaw;
|
|
417
|
+
} ? TRaw : unknown;
|
|
418
|
+
type MappedTypedError<Out extends ErrorResponse> = TypedError<Out['code'], ResolvedMeta<Out['meta']>, ResolvedRaw<Out>>;
|
|
412
419
|
declare class ErrorRuleBuilder<T> {
|
|
413
420
|
private readonly predicate;
|
|
414
421
|
constructor(predicate: (err: unknown) => err is T);
|
|
415
422
|
toCode<const C extends string>(code: C): ErrorMapper<T, C>;
|
|
416
|
-
toError<const Out extends ErrorResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<MappedTypedError<Out
|
|
423
|
+
toError<const Out extends ErrorResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<MappedTypedError<Out>>;
|
|
417
424
|
}
|
|
418
425
|
declare class ErrorMapper<T, C extends string> {
|
|
419
426
|
private readonly predicate;
|
|
420
427
|
private readonly errorCode;
|
|
421
428
|
constructor(predicate: (err: unknown) => err is T, errorCode: C);
|
|
422
|
-
with<const Out extends MapperResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<TypedError<C,
|
|
429
|
+
with<const Out extends MapperResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<TypedError<C, ResolvedMeta<Out['meta']>, ResolvedRaw<Out>>>;
|
|
423
430
|
}
|
|
424
431
|
|
|
425
432
|
declare const errorRule: {
|
|
@@ -436,9 +443,13 @@ declare const errorRule: {
|
|
|
436
443
|
readonly cause?: unknown;
|
|
437
444
|
} ? ErrorRule<AnyTypedError> & {
|
|
438
445
|
toCode: <const C extends string>(code: C) => ErrorMapper<InstanceType<T>, C>;
|
|
439
|
-
toError: <const Out extends ErrorResponse>(mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>) => ErrorRule<TypedError<Out["code"], Out["meta"] extends
|
|
446
|
+
toError: <const Out extends ErrorResponse>(mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>) => ErrorRule<TypedError<Out["code"], Out["meta"] extends infer T_1 ? T_1 extends Out["meta"] ? T_1 extends Record<string, unknown> ? T_1 : Record<string, unknown> : never : never, Out extends {
|
|
447
|
+
raw: infer TRaw;
|
|
448
|
+
} ? TRaw : unknown>>;
|
|
440
449
|
} : ErrorRuleBuilder<InstanceType<T>>;
|
|
441
|
-
<T extends abstract new (...args: never[]) => unknown, const Out extends ErrorResponse>(ErrorClass: T, mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>): ErrorRule<TypedError<Out["code"], Out["meta"] extends
|
|
450
|
+
<T extends abstract new (...args: never[]) => unknown, const Out extends ErrorResponse>(ErrorClass: T, mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>): ErrorRule<TypedError<Out["code"], Out["meta"] extends infer T_1 ? T_1 extends Out["meta"] ? T_1 extends Record<string, unknown> ? T_1 : Record<string, unknown> : never : never, Out extends {
|
|
451
|
+
raw: infer TRaw;
|
|
452
|
+
} ? TRaw : unknown>>;
|
|
442
453
|
};
|
|
443
454
|
};
|
|
444
455
|
|
package/dist/index.d.ts
CHANGED
|
@@ -16,16 +16,17 @@ declare const asRetryCount: (n: number) => RetryCount;
|
|
|
16
16
|
* Provides type-safe error handling with fluent API and metadata support
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
type DefaultErrorMeta = Record<string, unknown>;
|
|
20
|
+
declare abstract class TypedError<Code extends string = string, Meta extends object = DefaultErrorMeta, Raw = unknown> extends Error {
|
|
20
21
|
abstract readonly code: Code;
|
|
21
|
-
|
|
22
|
+
cause?: unknown;
|
|
22
23
|
readonly title?: string;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
meta: Meta;
|
|
25
|
+
status?: number;
|
|
26
|
+
raw?: Raw;
|
|
27
|
+
path?: string;
|
|
27
28
|
readonly timestamp: number;
|
|
28
|
-
|
|
29
|
+
retryable: boolean;
|
|
29
30
|
constructor(message: string, opts: {
|
|
30
31
|
title?: string;
|
|
31
32
|
cause?: unknown;
|
|
@@ -35,10 +36,10 @@ declare abstract class TypedError<Code extends string = string, Meta extends Rec
|
|
|
35
36
|
raw?: Raw;
|
|
36
37
|
path?: string;
|
|
37
38
|
});
|
|
38
|
-
is<C extends string>(code: C): this is TypedError<C> & {
|
|
39
|
+
is<C extends string>(code: C): this is TypedError<C, Meta, Raw> & {
|
|
39
40
|
code: C;
|
|
40
41
|
};
|
|
41
|
-
withMeta<const M>(meta: M): this & {
|
|
42
|
+
withMeta<const M extends object>(meta: M): this & {
|
|
42
43
|
meta: M;
|
|
43
44
|
};
|
|
44
45
|
withStatus(status: number): this & {
|
|
@@ -54,42 +55,42 @@ declare abstract class TypedError<Code extends string = string, Meta extends Rec
|
|
|
54
55
|
withRetryable(retryable: boolean): this;
|
|
55
56
|
toJSON(): Record<string, unknown>;
|
|
56
57
|
}
|
|
57
|
-
type AnyTypedError = TypedError
|
|
58
|
-
declare class TimeoutError extends TypedError<'TIMEOUT'
|
|
58
|
+
type AnyTypedError = TypedError;
|
|
59
|
+
declare class TimeoutError extends TypedError<'TIMEOUT'> {
|
|
59
60
|
readonly code: "TIMEOUT";
|
|
60
61
|
constructor(timeout: Milliseconds, cause?: unknown);
|
|
61
62
|
}
|
|
62
|
-
declare class AbortedError extends TypedError<'ABORTED'
|
|
63
|
+
declare class AbortedError extends TypedError<'ABORTED'> {
|
|
63
64
|
readonly code: "ABORTED";
|
|
64
65
|
constructor(reason?: string, cause?: unknown);
|
|
65
66
|
}
|
|
66
|
-
declare class CircuitOpenError extends TypedError<'CIRCUIT_OPEN'
|
|
67
|
+
declare class CircuitOpenError extends TypedError<'CIRCUIT_OPEN'> {
|
|
67
68
|
readonly code: "CIRCUIT_OPEN";
|
|
68
69
|
constructor(resetAfter: Milliseconds, cause?: unknown);
|
|
69
70
|
}
|
|
70
|
-
type ValidationMeta =
|
|
71
|
+
type ValidationMeta = {
|
|
71
72
|
validationErrors: unknown[];
|
|
72
73
|
};
|
|
73
|
-
declare class ValidationError extends TypedError<'VALIDATION', ValidationMeta
|
|
74
|
+
declare class ValidationError extends TypedError<'VALIDATION', ValidationMeta> {
|
|
74
75
|
readonly validationErrors: unknown[];
|
|
75
76
|
readonly code: "VALIDATION";
|
|
76
77
|
constructor(message: string, validationErrors: unknown[], cause?: unknown);
|
|
77
78
|
}
|
|
78
|
-
declare class NetworkError extends TypedError<'NETWORK'
|
|
79
|
+
declare class NetworkError extends TypedError<'NETWORK'> {
|
|
79
80
|
readonly statusCode?: number | undefined;
|
|
80
81
|
readonly code: "NETWORK";
|
|
81
82
|
constructor(message: string, statusCode?: number | undefined, cause?: unknown);
|
|
82
83
|
}
|
|
83
|
-
type HttpMeta =
|
|
84
|
+
type HttpMeta = {
|
|
84
85
|
response?: unknown;
|
|
85
86
|
};
|
|
86
|
-
declare class HttpError extends TypedError<'HTTP', HttpMeta
|
|
87
|
+
declare class HttpError extends TypedError<'HTTP', HttpMeta> {
|
|
87
88
|
readonly status: number;
|
|
88
89
|
readonly response?: unknown | undefined;
|
|
89
90
|
readonly code: "HTTP";
|
|
90
91
|
constructor(message: string, status: number, response?: unknown | undefined, cause?: unknown);
|
|
91
92
|
}
|
|
92
|
-
declare class UnknownError extends TypedError<'UNKNOWN'
|
|
93
|
+
declare class UnknownError extends TypedError<'UNKNOWN'> {
|
|
93
94
|
readonly code: "UNKNOWN";
|
|
94
95
|
constructor(message: string, cause?: unknown);
|
|
95
96
|
}
|
|
@@ -408,18 +409,24 @@ interface MapperResponse {
|
|
|
408
409
|
path?: string;
|
|
409
410
|
}
|
|
410
411
|
type Strict<T, Shape> = T & Record<Exclude<keyof T, keyof Shape>, never>;
|
|
411
|
-
type
|
|
412
|
+
type ResolvedMeta<TMeta> = TMeta extends Record<string, unknown> ? TMeta : Record<string, unknown>;
|
|
413
|
+
type ResolvedRaw<Out extends {
|
|
414
|
+
raw?: unknown;
|
|
415
|
+
}> = Out extends {
|
|
416
|
+
raw: infer TRaw;
|
|
417
|
+
} ? TRaw : unknown;
|
|
418
|
+
type MappedTypedError<Out extends ErrorResponse> = TypedError<Out['code'], ResolvedMeta<Out['meta']>, ResolvedRaw<Out>>;
|
|
412
419
|
declare class ErrorRuleBuilder<T> {
|
|
413
420
|
private readonly predicate;
|
|
414
421
|
constructor(predicate: (err: unknown) => err is T);
|
|
415
422
|
toCode<const C extends string>(code: C): ErrorMapper<T, C>;
|
|
416
|
-
toError<const Out extends ErrorResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<MappedTypedError<Out
|
|
423
|
+
toError<const Out extends ErrorResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<MappedTypedError<Out>>;
|
|
417
424
|
}
|
|
418
425
|
declare class ErrorMapper<T, C extends string> {
|
|
419
426
|
private readonly predicate;
|
|
420
427
|
private readonly errorCode;
|
|
421
428
|
constructor(predicate: (err: unknown) => err is T, errorCode: C);
|
|
422
|
-
with<const Out extends MapperResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<TypedError<C,
|
|
429
|
+
with<const Out extends MapperResponse>(mapper: (err: T) => Strict<Out, ErrorResponse>): ErrorRule<TypedError<C, ResolvedMeta<Out['meta']>, ResolvedRaw<Out>>>;
|
|
423
430
|
}
|
|
424
431
|
|
|
425
432
|
declare const errorRule: {
|
|
@@ -436,9 +443,13 @@ declare const errorRule: {
|
|
|
436
443
|
readonly cause?: unknown;
|
|
437
444
|
} ? ErrorRule<AnyTypedError> & {
|
|
438
445
|
toCode: <const C extends string>(code: C) => ErrorMapper<InstanceType<T>, C>;
|
|
439
|
-
toError: <const Out extends ErrorResponse>(mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>) => ErrorRule<TypedError<Out["code"], Out["meta"] extends
|
|
446
|
+
toError: <const Out extends ErrorResponse>(mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>) => ErrorRule<TypedError<Out["code"], Out["meta"] extends infer T_1 ? T_1 extends Out["meta"] ? T_1 extends Record<string, unknown> ? T_1 : Record<string, unknown> : never : never, Out extends {
|
|
447
|
+
raw: infer TRaw;
|
|
448
|
+
} ? TRaw : unknown>>;
|
|
440
449
|
} : ErrorRuleBuilder<InstanceType<T>>;
|
|
441
|
-
<T extends abstract new (...args: never[]) => unknown, const Out extends ErrorResponse>(ErrorClass: T, mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>): ErrorRule<TypedError<Out["code"], Out["meta"] extends
|
|
450
|
+
<T extends abstract new (...args: never[]) => unknown, const Out extends ErrorResponse>(ErrorClass: T, mapper: (err: InstanceType<T>) => Out & Record<Exclude<keyof Out, keyof ErrorResponse>, never>): ErrorRule<TypedError<Out["code"], Out["meta"] extends infer T_1 ? T_1 extends Out["meta"] ? T_1 extends Record<string, unknown> ? T_1 : Record<string, unknown> : never : never, Out extends {
|
|
451
|
+
raw: infer TRaw;
|
|
452
|
+
} ? TRaw : unknown>>;
|
|
442
453
|
};
|
|
443
454
|
};
|
|
444
455
|
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var le=Object.defineProperty;var de=(e,r,t)=>r in e?le(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var d=(e,r,t)=>de(e,typeof r!="symbol"?r+"":r,t);var E=class extends Error{constructor(t,n){var o,s;super(t);d(this,"cause");d(this,"title");d(this,"meta");d(this,"status");d(this,"raw");d(this,"path");d(this,"timestamp");d(this,"retryable");this.timestamp=Date.now(),this.retryable=(o=n.retryable)!=null?o:!0,this.name=this.constructor.name,this.cause=n.cause,this.title=n.title,this.meta=(s=n.meta)!=null?s:{},this.status=n.status,this.raw=n.raw,this.path=n.path,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}is(t){return this.code===t}withMeta(t){return Object.assign(this,{meta:t})}withStatus(t){return Object.assign(this,{status:t})}withCause(t){return Object.assign(this,{cause:t})}withPath(t){return this.path=t,this}withRaw(t){return Object.assign(this,{raw:t})}withRetryable(t){return this.retryable=t,this}toJSON(){return{name:this.name,code:this.code,title:this.title,message:this.message,timestamp:this.timestamp,retryable:this.retryable,cause:this.cause,raw:this.raw,path:this.path,stack:this.stack}}},P=class extends E{constructor(t,n){super(`Operation timed out after ${t}ms`,{cause:n,retryable:!0});d(this,"code","TIMEOUT")}};var F=class extends E{constructor(t,n){super(`Circuit breaker is open, reset after ${t}ms`,{cause:n,retryable:!1});d(this,"code","CIRCUIT_OPEN")}};var B=class extends E{constructor(t,n){super(t,{cause:n});d(this,"code","UNKNOWN")}};var b=e=>{if(e<0||!Number.isFinite(e))throw new Error(`Invalid milliseconds: must be a non-negative finite number, got ${e}`);return e},C=e=>{if(e<0||!Number.isInteger(e))throw new Error(`Invalid retry count: must be a non-negative integer, got ${e}`);return e},q=e=>{if(e<1||!Number.isInteger(e))throw new Error(`Invalid concurrency limit: must be a positive integer, got ${e}`);return e},Q=e=>{if(e<0||e>100||!Number.isFinite(e))throw new Error(`Invalid percentage: must be between 0 and 100, got ${e}`);return e};var _=class{constructor(r){d(this,"state");d(this,"config");this.config={failureThreshold:C(r.failureThreshold),resetTimeout:b(r.resetTimeout),halfOpenRequests:C(r.halfOpenRequests),shouldCountAsFailure:r.shouldCountAsFailure},this.state={state:"closed",failureCount:0,halfOpenCount:0}}async canExecute(){if(this.updateStateIfNeeded(),this.state.state==="open")return!1;if(this.state.state==="half-open"){if(this.state.halfOpenCount>=this.config.halfOpenRequests)return!1;this.state={...this.state,halfOpenCount:this.state.halfOpenCount+1}}return!0}async recordSuccess(){switch(this.state.state){case"closed":this.state={...this.state,failureCount:0};break;case"half-open":this.state={state:"closed",failureCount:0,halfOpenCount:0};break;case"open":break}}async recordFailure(r){var o,s,a;if(!((a=(s=(o=this.config).shouldCountAsFailure)==null?void 0:s.call(o,r))!=null?a:!0))return;let n=new Date;switch(this.state.state){case"closed":{let i=this.state.failureCount+1;i>=this.config.failureThreshold?this.state={state:"open",failureCount:i,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)}:this.state={...this.state,failureCount:i,lastFailureTime:n};break}case"half-open":this.state={state:"open",failureCount:this.state.failureCount+1,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break;case"open":this.state={...this.state,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break}}getState(){return this.updateStateIfNeeded(),{...this.state,canExecute:this.state.state!=="open"}}createOpenError(){let r=this.state.nextAttemptTime?b(Math.max(0,this.state.nextAttemptTime.getTime()-Date.now())):this.config.resetTimeout;return new F(r)}forceState(r){this.state={state:r,failureCount:0,halfOpenCount:0}}reset(){this.state={state:"closed",failureCount:0,halfOpenCount:0}}updateStateIfNeeded(){this.state.state==="open"&&this.state.nextAttemptTime&&new Date>=this.state.nextAttemptTime&&(this.state={...this.state,state:"half-open",halfOpenCount:0})}};var X=(e,r)=>t=>{for(let n of e){let o=n(t);if(o!==null)return o}return r(t)},Z=e=>r=>r instanceof E?r:r instanceof Error?new e(r.message,r):typeof r=="string"?new e(r):new e("Unknown error occurred",r);var ye=e=>{let t=e.toString().match(/\bcode\s*:\s*['"`]([^'"`]+)['"`]/);return t==null?void 0:t[1]},pe=e=>{if(typeof e!="object"||e===null)return!1;let r=e;return typeof r.status=="number"||typeof r.statusCode=="number"},me=e=>{if(typeof e!="object"||e===null)return!1;let r=e;return typeof r.code=="string"&&r.code.length>0},fe=e=>{var r;if(e instanceof Error){let t=e.message.toLowerCase();if(e.name==="TypeError"&&(t.includes("fetch")&&t.includes("failed")||t.includes("network"))||t.includes("fetch")&&t.includes("failed")||t.includes("network"))return!0}if(me(e)){let t=((r=e.code)!=null?r:"").toUpperCase();return t==="ECONNRESET"||t==="ECONNREFUSED"||t==="ETIMEDOUT"||t==="ENOTFOUND"||t==="EAI_AGAIN"}return!1},Ee=e=>typeof e=="object"&&e!==null,U=class{constructor(r){this.predicate=r}toCode(r){return new W(this.predicate,r)}toError(r){let t=o=>{var c;if(!this.predicate(o))return null;let s=r(o),a=s.code,i=Object.hasOwn(s,"cause")?s.cause:o,l=(c=s.meta)!=null?c:{};class u extends E{constructor(){let m=Object.hasOwn(s,"raw")?s.raw:o;super(s.message,{title:s.title,cause:i,meta:l,status:s.status,retryable:s.retryable,raw:m,path:s.path});d(this,"code",a)}}return new u},n=ye(r);return n&&(t.__tryoCode=n),t}};function Te(e,r){let t=new U(s=>s instanceof e);if(r)return t.toError(r);let o=s=>{if(!(s instanceof e))return null;if(s instanceof E)return s;let a=s,i=typeof a.code=="string"&&a.code.length>0?a.code:"UNKNOWN",l=Object.hasOwn(a,"cause"),u=Object.hasOwn(a,"raw");class c extends E{constructor(){super(a.message||i,{title:typeof a.title=="string"?a.title:void 0,cause:l?a.cause:s,meta:Ee(a.meta)?a.meta:{},status:typeof a.status=="number"?a.status:void 0,retryable:typeof a.retryable=="boolean"?a.retryable:void 0,raw:u?a.raw:s,path:typeof a.path=="string"?a.path:void 0});d(this,"code",i)}}return new c};return o.toCode=t.toCode.bind(t),o.toError=t.toError.bind(t),o}var W=class{constructor(r,t){this.predicate=r;this.errorCode=t}with(r){let t=n=>{var u;if(!this.predicate(n))return null;let o=r(n),s=Object.hasOwn(o,"cause")?o.cause:n,a=(u=o.meta)!=null?u:{},i=this.errorCode;class l extends E{constructor(){let m=Object.hasOwn(o,"raw")?o.raw:n;super(o.message,{title:o.title,cause:s,meta:a,status:o.status,retryable:o.retryable,raw:m,path:o.path});d(this,"code",i)}}return new l};return t.__tryoCode=this.errorCode,t}},h={when:e=>new U(e),instance:Te},x={typed:(e=>e instanceof E?e:null),abort:h.when(e=>e instanceof Error&&e.name==="AbortError").toCode("ABORTED").with(e=>({message:e.message||"Operation was aborted",cause:e,retryable:!1,raw:e})),timeout:h.when(e=>e instanceof Error&&e.name==="TimeoutError").toCode("TIMEOUT").with(e=>({message:e.message||"Operation timed out",cause:e,raw:e})),network:h.when(e=>fe(e)).toCode("NETWORK").with(e=>({message:(e instanceof Error,e.message||"Network error"),cause:e,raw:e})),http:h.when(e=>{var n;if(!pe(e))return!1;let r=e,t=(n=r.status)!=null?n:r.statusCode;return typeof t=="number"&&t>=400}).toCode("HTTP").with(e=>{var n;let r=(n=e.status)!=null?n:e.statusCode,t=typeof r=="number"&&(r>=500||r===429);return{message:e.message||`HTTP ${r!=null?r:"error"} error`,cause:e,status:typeof r=="number"?r:void 0,retryable:t,raw:e}}),unknown:h.when(e=>e instanceof Error&&!(e instanceof E)).toCode("UNKNOWN").with(e=>({message:e.message||"Unknown error occurred",cause:e,raw:e}))};var we=[x.typed,x.abort,x.timeout,x.http,x.network,x.unknown];var be={when:e=>h.when(e),instance:h.instance},ee=we;var he={fixed:e=>({type:"fixed",delay:e}),exponential:(e,r=2,t)=>({type:"exponential",base:e,factor:r,maxDelay:t}),fibonacci:(e,r)=>({type:"fibonacci",base:e,maxDelay:r}),custom:e=>({type:"custom",calculate:e})},re=(e,r,t)=>{switch(e.type){case"fixed":return e.delay;case"exponential":{let n=e.base*e.factor**(Number(r)-1);return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"fibonacci":{let n=e.base*Re(Number(r));return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"custom":return e.calculate(r,t);default:return e}},Re=e=>{if(e<=1)return 1;let r=1,t=1;for(let n=2;n<=e;n++){let o=r+t;r=t,t=o}return t},te=e=>{switch(e.type){case"fixed":{if(e.delay<0)throw new Error("Fixed delay must be non-negative");break}case"exponential":if(e.base<=0)throw new Error("Exponential base delay must be positive");if(e.factor<=1)throw new Error("Exponential factor must be greater than 1");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Exponential max delay must be positive");break;case"fibonacci":if(e.base<=0)throw new Error("Fibonacci base delay must be positive");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Fibonacci max delay must be positive");break;case"custom":break;default:{let r=e;throw new Error(`Unknown strategy type: ${r}`)}}};var ne=(e,r)=>new Promise((t,n)=>{if(r!=null&&r.aborted){n(new DOMException("Aborted","AbortError"));return}let o=i=>{r&&i&&r.removeEventListener("abort",i)},s,a=()=>{s&&clearTimeout(s),o(a),n(new DOMException("Aborted","AbortError"))};s=setTimeout(()=>{o(a),t()},e),r==null||r.addEventListener("abort",a,{once:!0})}),oe=(e,r,t,n)=>new Promise((o,s)=>{if(t!=null&&t.aborted){s(new DOMException("Aborted","AbortError"));return}let a=!1,i=setTimeout(()=>{var c;a=!0,u(),s((c=n==null?void 0:n())!=null?c:new Error(`Operation timed out after ${r}ms`))},r),l=()=>{a||(a=!0,u(),s(new DOMException("Aborted","AbortError")))},u=()=>{clearTimeout(i),t==null||t.removeEventListener("abort",l)};t==null||t.addEventListener("abort",l,{once:!0}),e.then(c=>{a||(a=!0,u(),o(c))},c=>{a||(a=!0,u(),s(c))})});var Ce=e=>{var a,i,l;if(e.toError)return e.toError;let r=(a=e.rulesMode)!=null?a:"extend",t=(i=e.rules)!=null?i:[];xe(t);let n=ee,o=(l=e.fallback)!=null?l:(u=>Z(B)(u)),s=r==="replace"?t:[...t,...n];return X(s,o)},xe=e=>{let r=new Set;for(let t of e){let n=t.__tryoCode;if(n){if(r.has(n))throw new Error(`Duplicate rule code detected: ${n}`);r.add(n)}}},ge=e=>{if(e)switch(e.type){case"none":return;case"full":case"equal":Q(e.ratio);return;case"custom":return;default:{let r=e;throw new Error(`Unsupported jitter configuration: ${r}`)}}},K=e=>{let r=e;return r.timeout!==void 0&&(r={...r,timeout:Number(b(r.timeout))}),r.concurrency!==void 0&&(r={...r,concurrency:Number.isFinite(r.concurrency)?Number(q(r.concurrency)):r.concurrency}),r.retry&&(te(r.retry.strategy),ge(r.retry.jitter),r={...r,retry:{...r.retry,maxRetries:Number(C(r.retry.maxRetries))}}),r},V=class e{constructor(r={}){d(this,"circuitBreaker");d(this,"config");d(this,"lastCircuitState");let{rules:t,rulesMode:n,fallback:o,toError:s,mapError:a,...i}=r,l=Ce(r),u={...i,errorHandling:{normalizer:l,mapError:a}};this.config=K(u),u.circuitBreaker&&(this.circuitBreaker=new _(u.circuitBreaker),this.lastCircuitState=this.circuitBreaker.getState().state)}async run(r,t={}){var s,a,i,l;let n=K({...this.config,...t});if(this.circuitBreaker){let u=(s=this.lastCircuitState)!=null?s:this.circuitBreaker.getState().state,c=await this.circuitBreaker.canExecute(),y=this.circuitBreaker.getState().state;if(u!==y)try{(a=n.onCircuitStateChange)==null||a.call(n,u,y)}catch{}if(this.lastCircuitState=y,!c)return{type:"failure",ok:!1,data:null,error:this.circuitBreaker.createOpenError(),metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,retryHistory:[]}}}let o=await ke(r,n);if(this.circuitBreaker){let u=(i=this.lastCircuitState)!=null?i:this.circuitBreaker.getState().state;o.ok?await this.circuitBreaker.recordSuccess():await this.circuitBreaker.recordFailure(o.error);let c=this.circuitBreaker.getState().state;if(u!==c)try{(l=n.onCircuitStateChange)==null||l.call(n,u,c)}catch{}this.lastCircuitState=c}return o}async runOrThrow(r,t={}){return this.orThrow(r,t)}async orThrow(r,t={}){let n=await this.run(r,t);if(n.ok)return n.data;throw n.error}async all(r,t={}){var c;let n=K({...this.config,...t}),o=(c=n.concurrency)!=null?c:Number.POSITIVE_INFINITY,s=Number.isFinite(o)?Number(q(o)):Number.POSITIVE_INFINITY;if(s===Number.POSITIVE_INFINITY)return Promise.all(r.map(y=>this.run(y,n)));let a=new Array(r.length),i=0,l=async()=>{var y;for(;i<r.length&&!((y=n.signal)!=null&&y.aborted);){let T=i++;if(T>=r.length)break;let m=r[T];m&&(a[T]=await this.run(m,n))}},u=Array.from({length:Math.min(s,r.length)},()=>l());await Promise.all(u);for(let y=0;y<r.length;y++)if(!(y in a)){let T=r[y];T&&(a[y]=await this.run(T,n))}return a}async allOrThrow(r,t={}){return(await this.all(r,t)).map(o=>{if(!o.ok)throw o.error;return o.data})}partitionAll(r){let t=[],n=[],o=[],s=[],a=[];for(let i of r){if(i.type==="success"){t.push(i);continue}switch(n.push(i),i.type){case"failure":o.push(i);break;case"aborted":s.push(i);break;case"timeout":a.push(i);break}}return{ok:t,errors:n,failure:o,aborted:s,timeout:a}}getCircuitBreakerState(){var r;return(r=this.circuitBreaker)==null?void 0:r.getState()}resetCircuitBreaker(){var r;(r=this.circuitBreaker)==null||r.reset()}getConfig(){return{...this.config}}withConfig(r){var l,u;let{errorHandling:t,...n}=this.config,{errorHandling:o,...s}=r,a=(l=o==null?void 0:o.normalizer)!=null?l:t.normalizer,i=(u=o==null?void 0:o.mapError)!=null?u:t.mapError;return new e({...n,...s,toError:a,mapError:i})}};function L(e={}){let r=new V(e);return{run:(t,n)=>r.run(t,n),orThrow:(t,n)=>r.orThrow(t,n),runOrThrow:(t,n)=>r.runOrThrow(t,n),all:(t,n)=>r.all(t,n),allOrThrow:(t,n)=>r.allOrThrow(t,n),partitionAll:t=>r.partitionAll(t),withConfig:t=>r.withConfig(t)}}async function ke(e,r){let{signal:t,ignoreAbort:n=!0,timeout:o,retry:s,errorHandling:a,logger:i,onSuccess:l,onError:u,onFinally:c,onAbort:y,onRetry:T}=r,m=(R,...p)=>{try{R==null||R(...p)}catch{}},M,k=0,g=[],z=Date.now(),{signal:I,cleanup:ae}=se(t),O=R=>({totalAttempts:k,totalRetries:k>0?Number(k)-1:0,totalDuration:Date.now()-z,lastError:R,retryHistory:g});try{if(I.aborted){m(y,I);let p=a.normalizer(new DOMException("Aborted","AbortError")),w=a.mapError?a.mapError(p):p;return{type:"aborted",ok:!1,data:null,error:w,metrics:O(w)}}let R=async()=>{var v,A,J;let p=1,w=C((v=s==null?void 0:s.maxRetries)!=null?v:0);for(;;){k=p;let j=new AbortController,{signal:H,cleanup:ie}=se(I,j.signal);try{let D=Promise.resolve(e({signal:H})),S=o?await oe(D,o,H,()=>(j.abort(),new P(b(o)))):await D;return m(l,S,O()),m(i==null?void 0:i.info,`Task succeeded on attempt ${p}`),S}catch(D){let S=a.normalizer(D),f=a.mapError?a.mapError(S):S;if(M=f,f.code==="ABORTED"&&m(y,H),n&&f.code==="ABORTED"||(m(u,f,O(f)),m(i==null?void 0:i.error,`Task failed on attempt ${p}`,f)),f.code==="ABORTED"||f.retryable===!1)throw f;if(p<=Number(w)){let Y=s==null?void 0:s.shouldRetry,ue={totalAttempts:Number(k),elapsedTime:Date.now()-z,startTime:new Date(z),lastDelay:(A=g[g.length-1])!=null&&A.delay?Number((J=g[g.length-1])==null?void 0:J.delay):void 0};if(!Y||Y(p,f,ue)){let ce=s?re(s.strategy,p,f):0,$=Oe(ce,s==null?void 0:s.jitter),G=b($);g.push({attempt:p,error:f,delay:G,timestamp:new Date}),m(T,p,f,$),m(i==null?void 0:i.info,`Retrying in ${$}ms (attempt ${p+1})`),p+=1,await ne(G,I);continue}}throw f}finally{ie()}}};try{let p=await R(),w=O();return m(c,w),{type:"success",ok:!0,data:p,error:null,metrics:w}}catch(p){let w=M!=null?M:a.normalizer(p),v=w.code==="TIMEOUT"?"timeout":w.code==="ABORTED"?"aborted":"failure",A=O(w);return m(c,A),{type:v,ok:!1,data:null,error:w,metrics:A}}}finally{ae()}}function se(...e){let r=new AbortController,t=e.filter(o=>o!==void 0);if(t.length===0)return{signal:r.signal,cleanup:()=>{}};if(t.some(o=>o.aborted))return r.abort(),{signal:r.signal,cleanup:()=>{}};let n=[];for(let o of t){let s=()=>r.abort();o.addEventListener("abort",s,{once:!0}),n.push({signal:o,abort:s})}return{signal:r.signal,cleanup:()=>{for(let o of n)o.signal.removeEventListener("abort",o.abort)}}}function Oe(e,r){if(!r||r.type==="none"||e<=0)return e;switch(r.type){case"full":{let t=Number(r.ratio)/100,n=Math.max(0,Number(e)*(1-t)),o=Number(e);return n+Math.random()*(o-n)}case"equal":{let t=Number(r.ratio)/100,n=Number(e)*t/2;return Number(e)-n+Math.random()*n}case"custom":return r.calculate(e);default:return r}}var N=L(),Ae=N.run,Se=N.runOrThrow,Ne=N.orThrow,Me=N.all,Ie=N.allOrThrow;export{he as RetryStrategies,E as TypedError,Me as all,Ie as allOrThrow,b as asMilliseconds,C as asRetryCount,L as default,be as errorRule,Ne as orThrow,Ae as run,Se as runOrThrow,L as tryo};
|
|
1
|
+
var le=Object.defineProperty;var de=(e,t,r)=>t in e?le(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var d=(e,t,r)=>de(e,typeof t!="symbol"?t+"":t,r);var E=class extends Error{constructor(r,n){var o,s;super(r);d(this,"cause");d(this,"title");d(this,"meta");d(this,"status");d(this,"raw");d(this,"path");d(this,"timestamp");d(this,"retryable");this.timestamp=Date.now(),this.retryable=(o=n.retryable)!=null?o:!0,this.name=this.constructor.name,this.cause=n.cause,this.title=n.title,this.meta=(s=n.meta)!=null?s:{},this.status=n.status,this.raw=n.raw,this.path=n.path,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}is(r){return this.code===r}withMeta(r){return this.meta=r,this}withStatus(r){return this.status=r,this}withCause(r){return this.cause=r,this}withPath(r){return this.path=r,this}withRaw(r){return this.raw=r,this}withRetryable(r){return this.retryable=r,this}toJSON(){return{name:this.name,code:this.code,title:this.title,message:this.message,meta:this.meta,status:this.status,timestamp:this.timestamp,retryable:this.retryable,cause:this.cause,raw:this.raw,path:this.path,stack:this.stack}}},P=class extends E{constructor(r,n){super(`Operation timed out after ${r}ms`,{cause:n,retryable:!0});d(this,"code","TIMEOUT")}};var F=class extends E{constructor(r,n){super(`Circuit breaker is open, reset after ${r}ms`,{cause:n,retryable:!1});d(this,"code","CIRCUIT_OPEN")}};var B=class extends E{constructor(r,n){super(r,{cause:n});d(this,"code","UNKNOWN")}};var b=e=>{if(e<0||!Number.isFinite(e))throw new Error(`Invalid milliseconds: must be a non-negative finite number, got ${e}`);return e},C=e=>{if(e<0||!Number.isInteger(e))throw new Error(`Invalid retry count: must be a non-negative integer, got ${e}`);return e},q=e=>{if(e<1||!Number.isInteger(e))throw new Error(`Invalid concurrency limit: must be a positive integer, got ${e}`);return e},Q=e=>{if(e<0||e>100||!Number.isFinite(e))throw new Error(`Invalid percentage: must be between 0 and 100, got ${e}`);return e};var _=class{constructor(t){d(this,"state");d(this,"config");this.config={failureThreshold:C(t.failureThreshold),resetTimeout:b(t.resetTimeout),halfOpenRequests:C(t.halfOpenRequests),shouldCountAsFailure:t.shouldCountAsFailure},this.state={state:"closed",failureCount:0,halfOpenCount:0}}async canExecute(){if(this.updateStateIfNeeded(),this.state.state==="open")return!1;if(this.state.state==="half-open"){if(this.state.halfOpenCount>=this.config.halfOpenRequests)return!1;this.state={...this.state,halfOpenCount:this.state.halfOpenCount+1}}return!0}async recordSuccess(){switch(this.state.state){case"closed":this.state={...this.state,failureCount:0};break;case"half-open":this.state={state:"closed",failureCount:0,halfOpenCount:0};break;case"open":break}}async recordFailure(t){var o,s,a;if(!((a=(s=(o=this.config).shouldCountAsFailure)==null?void 0:s.call(o,t))!=null?a:!0))return;let n=new Date;switch(this.state.state){case"closed":{let i=this.state.failureCount+1;i>=this.config.failureThreshold?this.state={state:"open",failureCount:i,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)}:this.state={...this.state,failureCount:i,lastFailureTime:n};break}case"half-open":this.state={state:"open",failureCount:this.state.failureCount+1,halfOpenCount:0,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break;case"open":this.state={...this.state,lastFailureTime:n,nextAttemptTime:new Date(n.getTime()+this.config.resetTimeout)};break}}getState(){return this.updateStateIfNeeded(),{...this.state,canExecute:this.state.state!=="open"}}createOpenError(){let t=this.state.nextAttemptTime?b(Math.max(0,this.state.nextAttemptTime.getTime()-Date.now())):this.config.resetTimeout;return new F(t)}forceState(t){this.state={state:t,failureCount:0,halfOpenCount:0}}reset(){this.state={state:"closed",failureCount:0,halfOpenCount:0}}updateStateIfNeeded(){this.state.state==="open"&&this.state.nextAttemptTime&&new Date>=this.state.nextAttemptTime&&(this.state={...this.state,state:"half-open",halfOpenCount:0})}};var X=(e,t)=>r=>{for(let n of e){let o=n(r);if(o!==null)return o}return t(r)},Z=e=>t=>t instanceof E?t:t instanceof Error?new e(t.message,t):typeof t=="string"?new e(t):new e("Unknown error occurred",t);var ye=e=>{let r=e.toString().match(/\bcode\s*:\s*['"`]([^'"`]+)['"`]/);return r==null?void 0:r[1]},pe=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.status=="number"||typeof t.statusCode=="number"},me=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.code=="string"&&t.code.length>0},fe=e=>{var t;if(e instanceof Error){let r=e.message.toLowerCase();if(e.name==="TypeError"&&(r.includes("fetch")&&r.includes("failed")||r.includes("network"))||r.includes("fetch")&&r.includes("failed")||r.includes("network"))return!0}if(me(e)){let r=((t=e.code)!=null?t:"").toUpperCase();return r==="ECONNRESET"||r==="ECONNREFUSED"||r==="ETIMEDOUT"||r==="ENOTFOUND"||r==="EAI_AGAIN"}return!1},Ee=e=>typeof e=="object"&&e!==null,U=class{constructor(t){this.predicate=t}toCode(t){return new W(this.predicate,t)}toError(t){let r=o=>{var c;if(!this.predicate(o))return null;let s=t(o),a=s.code,i=Object.hasOwn(s,"cause")?s.cause:o,l=(c=s.meta)!=null?c:{};class u extends E{constructor(){let m=Object.hasOwn(s,"raw")?s.raw:o;super(s.message,{title:s.title,cause:i,meta:l,status:s.status,retryable:s.retryable,raw:m,path:s.path});d(this,"code",a)}}return new u},n=ye(t);return n&&(r.__tryoCode=n),r}};function Te(e,t){let r=new U(s=>s instanceof e);if(t)return r.toError(t);let o=s=>{if(!(s instanceof e))return null;if(s instanceof E)return s;let a=s,i=typeof a.code=="string"&&a.code.length>0?a.code:"UNKNOWN",l=Object.hasOwn(a,"cause"),u=Object.hasOwn(a,"raw");class c extends E{constructor(){super(a.message||i,{title:typeof a.title=="string"?a.title:void 0,cause:l?a.cause:s,meta:Ee(a.meta)?a.meta:{},status:typeof a.status=="number"?a.status:void 0,retryable:typeof a.retryable=="boolean"?a.retryable:void 0,raw:u?a.raw:s,path:typeof a.path=="string"?a.path:void 0});d(this,"code",i)}}return new c};return o.toCode=r.toCode.bind(r),o.toError=r.toError.bind(r),o}var W=class{constructor(t,r){this.predicate=t;this.errorCode=r}with(t){let r=n=>{var u;if(!this.predicate(n))return null;let o=t(n),s=Object.hasOwn(o,"cause")?o.cause:n,a=(u=o.meta)!=null?u:{},i=this.errorCode;class l extends E{constructor(){let m=Object.hasOwn(o,"raw")?o.raw:n;super(o.message,{title:o.title,cause:s,meta:a,status:o.status,retryable:o.retryable,raw:m,path:o.path});d(this,"code",i)}}return new l};return r.__tryoCode=this.errorCode,r}},w={when:e=>new U(e),instance:Te},x={typed:(e=>e instanceof E?e:null),abort:w.when(e=>e instanceof Error&&e.name==="AbortError").toCode("ABORTED").with(e=>({message:e.message||"Operation was aborted",cause:e,retryable:!1,raw:e})),timeout:w.when(e=>e instanceof Error&&e.name==="TimeoutError").toCode("TIMEOUT").with(e=>({message:e.message||"Operation timed out",cause:e,raw:e})),network:w.when(e=>fe(e)).toCode("NETWORK").with(e=>({message:(e instanceof Error,e.message||"Network error"),cause:e,raw:e})),http:w.when(e=>{var n;if(!pe(e))return!1;let t=e,r=(n=t.status)!=null?n:t.statusCode;return typeof r=="number"&&r>=400}).toCode("HTTP").with(e=>{var n;let t=(n=e.status)!=null?n:e.statusCode,r=typeof t=="number"&&(t>=500||t===429);return{message:e.message||`HTTP ${t!=null?t:"error"} error`,cause:e,status:typeof t=="number"?t:void 0,retryable:r,raw:e}}),unknown:w.when(e=>e instanceof Error&&!(e instanceof E)).toCode("UNKNOWN").with(e=>({message:e.message||"Unknown error occurred",cause:e,raw:e}))};var he=[x.typed,x.abort,x.timeout,x.http,x.network,x.unknown];var be={when:e=>w.when(e),instance:w.instance},ee=he;var we={fixed:e=>({type:"fixed",delay:e}),exponential:(e,t=2,r)=>({type:"exponential",base:e,factor:t,maxDelay:r}),fibonacci:(e,t)=>({type:"fibonacci",base:e,maxDelay:t}),custom:e=>({type:"custom",calculate:e})},te=(e,t,r)=>{switch(e.type){case"fixed":return e.delay;case"exponential":{let n=e.base*e.factor**(Number(t)-1);return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"fibonacci":{let n=e.base*Re(Number(t));return e.maxDelay!==void 0?Math.min(n,e.maxDelay):n}case"custom":return e.calculate(t,r);default:return e}},Re=e=>{if(e<=1)return 1;let t=1,r=1;for(let n=2;n<=e;n++){let o=t+r;t=r,r=o}return r},re=e=>{switch(e.type){case"fixed":{if(e.delay<0)throw new Error("Fixed delay must be non-negative");break}case"exponential":if(e.base<=0)throw new Error("Exponential base delay must be positive");if(e.factor<=1)throw new Error("Exponential factor must be greater than 1");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Exponential max delay must be positive");break;case"fibonacci":if(e.base<=0)throw new Error("Fibonacci base delay must be positive");if(e.maxDelay!==void 0&&e.maxDelay<=0)throw new Error("Fibonacci max delay must be positive");break;case"custom":break;default:{let t=e;throw new Error(`Unknown strategy type: ${t}`)}}};var ne=(e,t)=>new Promise((r,n)=>{if(t!=null&&t.aborted){n(new DOMException("Aborted","AbortError"));return}let o=i=>{t&&i&&t.removeEventListener("abort",i)},s,a=()=>{s&&clearTimeout(s),o(a),n(new DOMException("Aborted","AbortError"))};s=setTimeout(()=>{o(a),r()},e),t==null||t.addEventListener("abort",a,{once:!0})}),oe=(e,t,r,n)=>new Promise((o,s)=>{if(r!=null&&r.aborted){s(new DOMException("Aborted","AbortError"));return}let a=!1,i=setTimeout(()=>{var c;a=!0,u(),s((c=n==null?void 0:n())!=null?c:new Error(`Operation timed out after ${t}ms`))},t),l=()=>{a||(a=!0,u(),s(new DOMException("Aborted","AbortError")))},u=()=>{clearTimeout(i),r==null||r.removeEventListener("abort",l)};r==null||r.addEventListener("abort",l,{once:!0}),e.then(c=>{a||(a=!0,u(),o(c))},c=>{a||(a=!0,u(),s(c))})});var Ce=e=>{var a,i,l;if(e.toError)return e.toError;let t=(a=e.rulesMode)!=null?a:"extend",r=(i=e.rules)!=null?i:[];xe(r);let n=ee,o=(l=e.fallback)!=null?l:(u=>Z(B)(u)),s=t==="replace"?r:[...r,...n];return X(s,o)},xe=e=>{let t=new Set;for(let r of e){let n=r.__tryoCode;if(n){if(t.has(n))throw new Error(`Duplicate rule code detected: ${n}`);t.add(n)}}},ge=e=>{if(e)switch(e.type){case"none":return;case"full":case"equal":Q(e.ratio);return;case"custom":return;default:{let t=e;throw new Error(`Unsupported jitter configuration: ${t}`)}}},K=e=>{let t=e;return t.timeout!==void 0&&(t={...t,timeout:Number(b(t.timeout))}),t.concurrency!==void 0&&(t={...t,concurrency:Number.isFinite(t.concurrency)?Number(q(t.concurrency)):t.concurrency}),t.retry&&(re(t.retry.strategy),ge(t.retry.jitter),t={...t,retry:{...t.retry,maxRetries:Number(C(t.retry.maxRetries))}}),t},V=class e{constructor(t={}){d(this,"circuitBreaker");d(this,"config");d(this,"lastCircuitState");let{rules:r,rulesMode:n,fallback:o,toError:s,mapError:a,...i}=t,l=Ce(t),u={...i,errorHandling:{normalizer:l,mapError:a}};this.config=K(u),u.circuitBreaker&&(this.circuitBreaker=new _(u.circuitBreaker),this.lastCircuitState=this.circuitBreaker.getState().state)}async run(t,r={}){var s,a,i,l;let n=K({...this.config,...r});if(this.circuitBreaker){let u=(s=this.lastCircuitState)!=null?s:this.circuitBreaker.getState().state,c=await this.circuitBreaker.canExecute(),y=this.circuitBreaker.getState().state;if(u!==y)try{(a=n.onCircuitStateChange)==null||a.call(n,u,y)}catch{}if(this.lastCircuitState=y,!c)return{type:"failure",ok:!1,data:null,error:this.circuitBreaker.createOpenError(),metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,retryHistory:[]}}}let o=await ke(t,n);if(this.circuitBreaker){let u=(i=this.lastCircuitState)!=null?i:this.circuitBreaker.getState().state;o.ok?await this.circuitBreaker.recordSuccess():await this.circuitBreaker.recordFailure(o.error);let c=this.circuitBreaker.getState().state;if(u!==c)try{(l=n.onCircuitStateChange)==null||l.call(n,u,c)}catch{}this.lastCircuitState=c}return o}async runOrThrow(t,r={}){return this.orThrow(t,r)}async orThrow(t,r={}){let n=await this.run(t,r);if(n.ok)return n.data;throw n.error}async all(t,r={}){var c;let n=K({...this.config,...r}),o=(c=n.concurrency)!=null?c:Number.POSITIVE_INFINITY,s=Number.isFinite(o)?Number(q(o)):Number.POSITIVE_INFINITY;if(s===Number.POSITIVE_INFINITY)return Promise.all(t.map(y=>this.run(y,n)));let a=new Array(t.length),i=0,l=async()=>{var y;for(;i<t.length&&!((y=n.signal)!=null&&y.aborted);){let T=i++;if(T>=t.length)break;let m=t[T];m&&(a[T]=await this.run(m,n))}},u=Array.from({length:Math.min(s,t.length)},()=>l());await Promise.all(u);for(let y=0;y<t.length;y++)if(!(y in a)){let T=t[y];T&&(a[y]=await this.run(T,n))}return a}async allOrThrow(t,r={}){return(await this.all(t,r)).map(o=>{if(!o.ok)throw o.error;return o.data})}partitionAll(t){let r=[],n=[],o=[],s=[],a=[];for(let i of t){if(i.type==="success"){r.push(i);continue}switch(n.push(i),i.type){case"failure":o.push(i);break;case"aborted":s.push(i);break;case"timeout":a.push(i);break}}return{ok:r,errors:n,failure:o,aborted:s,timeout:a}}getCircuitBreakerState(){var t;return(t=this.circuitBreaker)==null?void 0:t.getState()}resetCircuitBreaker(){var t;(t=this.circuitBreaker)==null||t.reset()}getConfig(){return{...this.config}}withConfig(t){var l,u;let{errorHandling:r,...n}=this.config,{errorHandling:o,...s}=t,a=(l=o==null?void 0:o.normalizer)!=null?l:r.normalizer,i=(u=o==null?void 0:o.mapError)!=null?u:r.mapError;return new e({...n,...s,toError:a,mapError:i})}};function L(e={}){let t=new V(e);return{run:(r,n)=>t.run(r,n),orThrow:(r,n)=>t.orThrow(r,n),runOrThrow:(r,n)=>t.runOrThrow(r,n),all:(r,n)=>t.all(r,n),allOrThrow:(r,n)=>t.allOrThrow(r,n),partitionAll:r=>t.partitionAll(r),withConfig:r=>t.withConfig(r)}}async function ke(e,t){let{signal:r,ignoreAbort:n=!0,timeout:o,retry:s,errorHandling:a,logger:i,onSuccess:l,onError:u,onFinally:c,onAbort:y,onRetry:T}=t,m=(R,...p)=>{try{R==null||R(...p)}catch{}},N,k=0,g=[],z=Date.now(),{signal:v,cleanup:ae}=se(r),O=R=>({totalAttempts:k,totalRetries:k>0?Number(k)-1:0,totalDuration:Date.now()-z,lastError:R,retryHistory:g});try{if(v.aborted){m(y,v);let p=a.normalizer(new DOMException("Aborted","AbortError")),h=a.mapError?a.mapError(p):p;return{type:"aborted",ok:!1,data:null,error:h,metrics:O(h)}}let R=async()=>{var I,A,J;let p=1,h=C((I=s==null?void 0:s.maxRetries)!=null?I:0);for(;;){k=p;let Y=new AbortController,{signal:H,cleanup:ie}=se(v,Y.signal);try{let D=Promise.resolve(e({signal:H})),S=o?await oe(D,o,H,()=>(Y.abort(),new P(b(o)))):await D;return m(l,S,O()),m(i==null?void 0:i.info,`Task succeeded on attempt ${p}`),S}catch(D){let S=a.normalizer(D),f=a.mapError?a.mapError(S):S;if(N=f,f.code==="ABORTED"&&m(y,H),n&&f.code==="ABORTED"||(m(u,f,O(f)),m(i==null?void 0:i.error,`Task failed on attempt ${p}`,f)),f.code==="ABORTED"||f.retryable===!1)throw f;if(p<=Number(h)){let j=s==null?void 0:s.shouldRetry,ue={totalAttempts:Number(k),elapsedTime:Date.now()-z,startTime:new Date(z),lastDelay:(A=g[g.length-1])!=null&&A.delay?Number((J=g[g.length-1])==null?void 0:J.delay):void 0};if(!j||j(p,f,ue)){let ce=s?te(s.strategy,p,f):0,$=Oe(ce,s==null?void 0:s.jitter),G=b($);g.push({attempt:p,error:f,delay:G,timestamp:new Date}),m(T,p,f,$),m(i==null?void 0:i.info,`Retrying in ${$}ms (attempt ${p+1})`),p+=1,await ne(G,v);continue}}throw f}finally{ie()}}};try{let p=await R(),h=O();return m(c,h),{type:"success",ok:!0,data:p,error:null,metrics:h}}catch(p){let h=N!=null?N:a.normalizer(p),I=h.code==="TIMEOUT"?"timeout":h.code==="ABORTED"?"aborted":"failure",A=O(h);return m(c,A),{type:I,ok:!1,data:null,error:h,metrics:A}}}finally{ae()}}function se(...e){let t=new AbortController,r=e.filter(o=>o!==void 0);if(r.length===0)return{signal:t.signal,cleanup:()=>{}};if(r.some(o=>o.aborted))return t.abort(),{signal:t.signal,cleanup:()=>{}};let n=[];for(let o of r){let s=()=>t.abort();o.addEventListener("abort",s,{once:!0}),n.push({signal:o,abort:s})}return{signal:t.signal,cleanup:()=>{for(let o of n)o.signal.removeEventListener("abort",o.abort)}}}function Oe(e,t){if(!t||t.type==="none"||e<=0)return e;switch(t.type){case"full":{let r=Number(t.ratio)/100,n=Math.max(0,Number(e)*(1-r)),o=Number(e);return n+Math.random()*(o-n)}case"equal":{let r=Number(t.ratio)/100,n=Number(e)*r/2;return Number(e)-n+Math.random()*n}case"custom":return t.calculate(e);default:return t}}var M=L(),Ae=M.run,Se=M.runOrThrow,Me=M.orThrow,Ne=M.all,ve=M.allOrThrow;export{we as RetryStrategies,E as TypedError,Ne as all,ve as allOrThrow,b as asMilliseconds,C as asRetryCount,L as default,be as errorRule,Me as orThrow,Ae as run,Se as runOrThrow,L as tryo};
|