tryo 0.13.8 → 0.13.9

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 CHANGED
@@ -1 +1 @@
1
- "use strict";var B=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var Re=Object.prototype.hasOwnProperty;var Ce=(e,r,t)=>r in e?B(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var xe=(e,r)=>{for(var t in r)B(e,t,{get:r[t],enumerable:!0})},ge=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of he(r))!Re.call(e,o)&&o!==t&&B(e,o,{get:()=>r[o],enumerable:!(n=be(r,o))||n.enumerable});return e};var ke=e=>ge(B({},"__esModule",{value:!0}),e);var l=(e,r,t)=>Ce(e,typeof r!="symbol"?r+"":r,t);var _e={};xe(_e,{RetryStrategies:()=>oe,TypedError:()=>m,all:()=>pe,allOrThrow:()=>me,asMilliseconds:()=>b,asRetryCount:()=>h,default:()=>S,errorRule:()=>te,orThrow:()=>ye,run:()=>le,runOrThrow:()=>de,tryo:()=>S});module.exports=ke(_e);var m=class extends Error{constructor(t,n){var o,a;super(t);l(this,"cause");l(this,"title");l(this,"meta");l(this,"status");l(this,"raw");l(this,"path");l(this,"timestamp");l(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=(a=n.meta)!=null?a:{},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}}},_=class extends m{constructor(t,n){super(`Operation timed out after ${t}ms`,{cause:n,retryable:!0});l(this,"code","TIMEOUT")}};var U=class extends m{constructor(t,n){super(`Circuit breaker is open, reset after ${t}ms`,{cause:n,retryable:!1});l(this,"code","CIRCUIT_OPEN")}};var L=class extends m{constructor(t,n){super(t,{cause:n});l(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},K=e=>{if(e<1||!Number.isInteger(e))throw new Error(`Invalid concurrency limit: must be a positive integer, got ${e}`);return e},Z=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 z=class{constructor(r){l(this,"state");l(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,a,s;if(!((s=(a=(o=this.config).shouldCountAsFailure)==null?void 0:a.call(o,r))!=null?s:!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 U(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 ee=(e,r)=>t=>{for(let n of e){let o=n(t);if(o!==null)return o}return r(t)},re=e=>r=>r instanceof m?r:r instanceof Error?new e(r.message,r):typeof r=="string"?new e(r):new e("Unknown error occurred",r);var 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,H=class{constructor(r){this.predicate=r}toCode(r){return new V(this.predicate,r)}toError(r){return t=>{var c;if(!this.predicate(t))return null;let n=r(t),o=n.code,a=Object.hasOwn(n,"cause")?n.cause:t,s=(c=n.meta)!=null?c:{};class i extends m{constructor(){let y=Object.hasOwn(n,"raw")?n.raw:t;super(n.message,{title:n.title,cause:a,meta:s,status:n.status,retryable:n.retryable,raw:y,path:n.path});l(this,"code",o)}}return new i}}};function Me(e,r){let t=new H(a=>a instanceof e);if(r)return t.toError(r);let o=a=>{if(!(a instanceof e))return null;if(a instanceof m)return a;let s=a,i=typeof s.code=="string"&&s.code.length>0?s.code:"UNKNOWN",c=Object.hasOwn(s,"cause"),u=Object.hasOwn(s,"raw");class d extends m{constructor(){super(s.message||i,{title:typeof s.title=="string"?s.title:void 0,cause:c?s.cause:a,meta:Ne(s.meta)?s.meta:{},status:typeof s.status=="number"?s.status:void 0,retryable:typeof s.retryable=="boolean"?s.retryable:void 0,raw:u?s.raw:a,path:typeof s.path=="string"?s.path:void 0});l(this,"code",i)}}return new d};return o.toCode=t.toCode.bind(t),o.toError=t.toError.bind(t),o}var V=class{constructor(r,t){this.predicate=r;this.errorCode=t}with(r){return t=>{var c;if(!this.predicate(t))return null;let n=r(t),o=Object.hasOwn(n,"cause")?n.cause:t,a=(c=n.meta)!=null?c:{},s=this.errorCode;class i extends m{constructor(){let T=Object.hasOwn(n,"raw")?n.raw:t;super(n.message,{title:n.title,cause:o,meta:a,status:n.status,retryable:n.retryable,raw:T,path:n.path});l(this,"code",s)}}return new i}}},R={when:e=>new H(e),instance:Me},g={typed:(e=>e instanceof m?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 m)).toCode("UNKNOWN").with(e=>({message:e.message||"Unknown error occurred",cause:e,raw:e}))};var Ie=[g.typed,g.abort,g.timeout,g.http,g.network,g.unknown];var te={when:e=>R.when(e),instance:R.instance},ne=Ie;var oe={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})},se=(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},ae=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 ie=(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)},a,s=()=>{a&&clearTimeout(a),o(s),n(new DOMException("Aborted","AbortError"))};a=setTimeout(()=>{o(s),t()},e),r==null||r.addEventListener("abort",s,{once:!0})}),ue=(e,r,t,n)=>new Promise((o,a)=>{if(t!=null&&t.aborted){a(new DOMException("Aborted","AbortError"));return}let s=!1,i=setTimeout(()=>{var d;s=!0,u(),a((d=n==null?void 0:n())!=null?d:new Error(`Operation timed out after ${r}ms`))},r),c=()=>{s||(s=!0,u(),a(new DOMException("Aborted","AbortError")))},u=()=>{clearTimeout(i),t==null||t.removeEventListener("abort",c)};t==null||t.addEventListener("abort",c,{once:!0}),e.then(d=>{s||(s=!0,u(),o(d))},d=>{s||(s=!0,u(),a(d))})});var De=e=>{var s,i,c;if(e.toError)return e.toError;let r=(s=e.rulesMode)!=null?s:"extend",t=(i=e.rules)!=null?i:[],n=ne,o=(c=e.fallback)!=null?c:(u=>re(L)(u)),a=r==="replace"?t:[...t,...n];return ee(a,o)},Pe=e=>{if(e)switch(e.type){case"none":return;case"full":case"equal":Z(e.ratio);return;case"custom":return;default:{let r=e;throw new Error(`Unsupported jitter configuration: ${r}`)}}},J=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(K(r.concurrency)):r.concurrency}),r.retry&&(ae(r.retry.strategy),Pe(r.retry.jitter),r={...r,retry:{...r.retry,maxRetries:Number(h(r.retry.maxRetries))}}),r},j=class e{constructor(r={}){l(this,"circuitBreaker");l(this,"config");l(this,"lastCircuitState");let{rules:t,rulesMode:n,fallback:o,toError:a,mapError:s,...i}=r,c=De(r),u={...i,errorHandling:{normalizer:c,mapError:s}};this.config=J(u),u.circuitBreaker&&(this.circuitBreaker=new z(u.circuitBreaker),this.lastCircuitState=this.circuitBreaker.getState().state)}async run(r,t={}){var a,s,i,c;let n=J({...this.config,...t});if(this.circuitBreaker){let u=(a=this.lastCircuitState)!=null?a:this.circuitBreaker.getState().state,d=await this.circuitBreaker.canExecute(),y=this.circuitBreaker.getState().state;if(u!==y)try{(s=n.onCircuitStateChange)==null||s.call(n,u,y)}catch{}if(this.lastCircuitState=y,!d)return{type:"failure",ok:!1,data:null,error:this.circuitBreaker.createOpenError(),metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,retryHistory:[]}}}let o=await Fe(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 d=this.circuitBreaker.getState().state;if(u!==d)try{(c=n.onCircuitStateChange)==null||c.call(n,u,d)}catch{}this.lastCircuitState=d}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 d;let n=J({...this.config,...t}),o=(d=n.concurrency)!=null?d:Number.POSITIVE_INFINITY,a=Number.isFinite(o)?Number(K(o)):Number.POSITIVE_INFINITY;if(a===Number.POSITIVE_INFINITY)return Promise.all(r.map(y=>this.run(y,n)));let s=new Array(r.length),i=0,c=async()=>{var y;for(;i<r.length&&!((y=n.signal)!=null&&y.aborted);){let T=i++;if(T>=r.length)break;let E=r[T];E&&(s[T]=await this.run(E,n))}},u=Array.from({length:Math.min(a,r.length)},()=>c());await Promise.all(u);for(let y=0;y<r.length;y++)if(!(y in s)){let T=r[y];T&&(s[y]=await this.run(T,n))}return s}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=[],a=[],s=[];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":a.push(i);break;case"timeout":s.push(i);break}}return{ok:t,errors:n,failure:o,aborted:a,timeout:s}}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 c,u;let{errorHandling:t,...n}=this.config,{errorHandling:o,...a}=r,s=(c=o==null?void 0:o.normalizer)!=null?c:t.normalizer,i=(u=o==null?void 0:o.mapError)!=null?u:t.mapError;return new e({...n,...a,toError:s,mapError:i})}};function S(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 Fe(e,r){let{signal:t,ignoreAbort:n=!0,timeout:o,retry:a,errorHandling:s,logger:i,onSuccess:c,onError:u,onFinally:d,onAbort:y,onRetry:T}=r,E=(x,...p)=>{try{x==null||x(...p)}catch{}},M,k=0,q=0,C=[],I=Date.now(),{signal:v,cleanup:fe}=ce(t),D=x=>({totalAttempts:k,totalRetries:k>0?Number(k)-1:0,totalDuration:Date.now()-I,lastError:x,retryHistory:C});try{if(v.aborted){E(y,v);let p=s.normalizer(new DOMException("Aborted","AbortError")),w=s.mapError?s.mapError(p):p;return{type:"aborted",ok:!1,data:null,error:w,metrics:{totalAttempts:k,totalRetries:q,totalDuration:Date.now()-I,lastError:w,retryHistory:C}}}let x=async()=>{var P,O,Y;let p=1,w=h((P=a==null?void 0:a.maxRetries)!=null?P:0);for(;;){k=p;let G=new AbortController,{signal:$,cleanup:Ee}=ce(v,G.signal);try{let F=Promise.resolve(e({signal:$})),A=o?await ue(F,o,$,()=>(G.abort(),new _(b(o)))):await F;return E(c,A,D()),E(i==null?void 0:i.info,`Task succeeded on attempt ${p}`),A}catch(F){let A=s.normalizer(F),f=s.mapError?s.mapError(A):A;if(M=f,f.code==="ABORTED"&&E(y,$),n&&f.code==="ABORTED"||(E(u,f,D(f)),E(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 Q=a==null?void 0:a.shouldRetry,we={totalAttempts:Number(k),elapsedTime:Date.now()-I,startTime:new Date(I),lastDelay:(O=C[C.length-1])!=null&&O.delay?Number((Y=C[C.length-1])==null?void 0:Y.delay):void 0};if(!Q||Q(p,f,we)){let Te=a?se(a.strategy,p,f):0,W=Be(Te,a==null?void 0:a.jitter),X=b(W);C.push({attempt:p,error:f,delay:X,timestamp:new Date}),E(T,p,f,W),E(i==null?void 0:i.info,`Retrying in ${W}ms (attempt ${p+1})`),p+=1,await ie(X,v);continue}}throw f}finally{Ee()}}};try{let p=await x(),w=D();return q=w.totalRetries,E(d,w),{type:"success",ok:!0,data:p,error:null,metrics:w}}catch(p){let w=M!=null?M:s.normalizer(p),P=w.code==="TIMEOUT"?"timeout":w.code==="ABORTED"?"aborted":"failure",O=D(w);return q=O.totalRetries,E(d,O),{type:P,ok:!1,data:null,error:w,metrics:O}}}finally{fe()}}function ce(...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 a=()=>r.abort();o.addEventListener("abort",a,{once:!0}),n.push({signal:o,abort:a})}return{signal:r.signal,cleanup:()=>{for(let o of n)o.signal.removeEventListener("abort",o.abort)}}}function Be(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=S(),le=N.run,de=N.runOrThrow,ye=N.orThrow,pe=N.all,me=N.allOrThrow;0&&(module.exports={RetryStrategies,TypedError,all,allOrThrow,asMilliseconds,asRetryCount,errorRule,orThrow,run,runOrThrow,tryo});
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});
package/dist/index.d.cts CHANGED
@@ -111,6 +111,46 @@ interface CircuitBreakerConfig<E extends AnyTypedError = AnyTypedError> {
111
111
  }
112
112
  type CircuitState = 'closed' | 'open' | 'half-open';
113
113
 
114
+ /**
115
+ * Modern error normalization system
116
+ * Provides type-safe error transformation and normalization
117
+ */
118
+
119
+ type ErrorNormalizer<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E;
120
+ type ErrorRule<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E | null;
121
+
122
+ /**
123
+ * Modern retry strategies with enhanced capabilities
124
+ * Provides various retry patterns with type safety
125
+ */
126
+
127
+ type RetryStrategy = FixedDelayStrategy | ExponentialBackoffStrategy | FibonacciBackoffStrategy | CustomDelayStrategy;
128
+ interface FixedDelayStrategy {
129
+ readonly type: 'fixed';
130
+ readonly delay: number;
131
+ }
132
+ interface ExponentialBackoffStrategy {
133
+ readonly type: 'exponential';
134
+ readonly base: number;
135
+ readonly factor: number;
136
+ readonly maxDelay?: number;
137
+ }
138
+ interface FibonacciBackoffStrategy {
139
+ readonly type: 'fibonacci';
140
+ readonly base: number;
141
+ readonly maxDelay?: number;
142
+ }
143
+ interface CustomDelayStrategy {
144
+ readonly type: 'custom';
145
+ readonly calculate: (attempt: RetryCount, error: unknown) => number;
146
+ }
147
+ declare const RetryStrategies: {
148
+ readonly fixed: (delay: number) => FixedDelayStrategy;
149
+ readonly exponential: (base: number, factor?: number, maxDelay?: number) => ExponentialBackoffStrategy;
150
+ readonly fibonacci: (base: number, maxDelay?: number) => FibonacciBackoffStrategy;
151
+ readonly custom: (calculate: (attempt: RetryCount, error: unknown) => number) => CustomDelayStrategy;
152
+ };
153
+
114
154
  /**
115
155
  * Modern result types with enhanced discriminated unions
116
156
  * Provides better type safety and more granular result categorization
@@ -122,30 +162,30 @@ interface SuccessResult<T, E extends AnyTypedError> {
122
162
  readonly ok: true;
123
163
  readonly data: T;
124
164
  readonly error: null;
125
- readonly metrics: TryoMetrics$1<E>;
165
+ readonly metrics: TryoMetrics<E>;
126
166
  }
127
167
  interface FailureResult<E extends AnyTypedError> {
128
168
  readonly type: 'failure';
129
169
  readonly ok: false;
130
170
  readonly data: null;
131
171
  readonly error: E;
132
- readonly metrics: TryoMetrics$1<E>;
172
+ readonly metrics: TryoMetrics<E>;
133
173
  }
134
174
  interface AbortedResult<E extends AnyTypedError> {
135
175
  readonly type: 'aborted';
136
176
  readonly ok: false;
137
177
  readonly data: null;
138
178
  readonly error: E;
139
- readonly metrics: TryoMetrics$1<E>;
179
+ readonly metrics: TryoMetrics<E>;
140
180
  }
141
181
  interface TimeoutResult<E extends AnyTypedError> {
142
182
  readonly type: 'timeout';
143
183
  readonly ok: false;
144
184
  readonly data: null;
145
185
  readonly error: E;
146
- readonly metrics: TryoMetrics$1<E>;
186
+ readonly metrics: TryoMetrics<E>;
147
187
  }
148
- interface TryoMetrics$1<E extends AnyTypedError> {
188
+ interface TryoMetrics<E extends AnyTypedError> {
149
189
  readonly totalAttempts: RetryCount;
150
190
  readonly totalRetries: RetryCount;
151
191
  readonly totalDuration: Milliseconds;
@@ -159,45 +199,10 @@ interface TryoMetrics$1<E extends AnyTypedError> {
159
199
  }
160
200
 
161
201
  /**
162
- * Modern error normalization system
163
- * Provides type-safe error transformation and normalization
164
- */
165
-
166
- type ErrorNormalizer<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E;
167
- type ErrorRule<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E | null;
168
-
169
- /**
170
- * Modern retry strategies with enhanced capabilities
171
- * Provides various retry patterns with type safety
202
+ * Configuration types for modern execution engine
203
+ * Provides comprehensive configuration with type safety
172
204
  */
173
205
 
174
- type RetryStrategy = FixedDelayStrategy | ExponentialBackoffStrategy | FibonacciBackoffStrategy | CustomDelayStrategy;
175
- interface FixedDelayStrategy {
176
- readonly type: 'fixed';
177
- readonly delay: number;
178
- }
179
- interface ExponentialBackoffStrategy {
180
- readonly type: 'exponential';
181
- readonly base: number;
182
- readonly factor: number;
183
- readonly maxDelay?: number;
184
- }
185
- interface FibonacciBackoffStrategy {
186
- readonly type: 'fibonacci';
187
- readonly base: number;
188
- readonly maxDelay?: number;
189
- }
190
- interface CustomDelayStrategy {
191
- readonly type: 'custom';
192
- readonly calculate: (attempt: RetryCount, error: unknown) => number;
193
- }
194
- declare const RetryStrategies: {
195
- readonly fixed: (delay: number) => FixedDelayStrategy;
196
- readonly exponential: (base: number, factor?: number, maxDelay?: number) => ExponentialBackoffStrategy;
197
- readonly fibonacci: (base: number, maxDelay?: number) => FibonacciBackoffStrategy;
198
- readonly custom: (calculate: (attempt: RetryCount, error: unknown) => number) => CustomDelayStrategy;
199
- };
200
-
201
206
  interface TryoConfig<E extends AnyTypedError = AnyTypedError> {
202
207
  /** Abort signal passed to tasks */
203
208
  readonly signal?: AbortSignal;
@@ -265,7 +270,6 @@ interface LoggerConfig<E extends AnyTypedError> {
265
270
  /** Warning logging function */
266
271
  readonly warn?: (message: string, meta?: unknown) => void;
267
272
  }
268
- type TryoMetrics<E extends AnyTypedError> = TryoMetrics$1<E>;
269
273
  type JitterConfig = {
270
274
  type: 'none';
271
275
  } | {
@@ -287,10 +291,17 @@ declare const JitterConfig: {
287
291
 
288
292
  type RulesMode = 'extend' | 'replace';
289
293
  type DefaultError = AbortedError | TimeoutError | NetworkError | HttpError | CircuitOpenError | ValidationError | UnknownError;
290
- type RunOptions<E extends AnyTypedError> = Omit<Partial<TryoConfig<E>>, 'circuitBreaker'>;
291
- type AllOptions<E extends AnyTypedError> = Omit<Partial<TryoConfig<E> & {
292
- concurrency?: number;
293
- }>, 'circuitBreaker'>;
294
+ type RunOptions<E extends AnyTypedError, TData = unknown> = Omit<Partial<TryoConfig<E>>, 'circuitBreaker' | 'onSuccess'> & {
295
+ onSuccess?: (data: TData, metrics?: TryoMetrics<E>) => void;
296
+ };
297
+ type AllOptions<E extends AnyTypedError, TData = unknown> = RunOptions<E, TData>;
298
+ type PartitionedResults<T, E extends AnyTypedError> = {
299
+ ok: Array<SuccessResult<T, E>>;
300
+ errors: Array<FailureResult<E> | AbortedResult<E> | TimeoutResult<E>>;
301
+ failure: Array<FailureResult<E>>;
302
+ aborted: Array<AbortedResult<E>>;
303
+ timeout: Array<TimeoutResult<E>>;
304
+ };
294
305
  type MaybePromise<T> = T | Promise<T>;
295
306
  type RuleLike = (error: unknown) => AnyTypedError | null;
296
307
  type NonNull<T> = T extends null ? never : T;
@@ -325,114 +336,48 @@ declare function tryo<E extends AnyTypedError = DefaultError>(options?: TryoOpti
325
336
  type Tryo<E extends AnyTypedError = AnyTypedError> = {
326
337
  run: <T>(task: (ctx: {
327
338
  signal: AbortSignal;
328
- }) => MaybePromise<T>, options?: RunOptions<E>) => Promise<TryoResult<T, E>>;
339
+ }) => MaybePromise<T>, options?: RunOptions<E, T>) => Promise<TryoResult<T, E>>;
329
340
  runOrThrow: <T>(task: (ctx: {
330
341
  signal: AbortSignal;
331
- }) => MaybePromise<T>, options?: RunOptions<E>) => Promise<T>;
342
+ }) => MaybePromise<T>, options?: RunOptions<E, T>) => Promise<T>;
332
343
  orThrow: <T>(task: (ctx: {
333
344
  signal: AbortSignal;
334
- }) => MaybePromise<T>, options?: RunOptions<E>) => Promise<T>;
345
+ }) => MaybePromise<T>, options?: RunOptions<E, T>) => Promise<T>;
335
346
  all: <T>(tasks: Array<(ctx: {
336
347
  signal: AbortSignal;
337
- }) => MaybePromise<T>>, options?: AllOptions<E>) => Promise<Array<TryoResult<T, E>>>;
348
+ }) => MaybePromise<T>>, options?: AllOptions<E, T>) => Promise<Array<TryoResult<T, E>>>;
338
349
  allOrThrow: <T>(tasks: Array<(ctx: {
339
350
  signal: AbortSignal;
340
- }) => MaybePromise<T>>, options?: AllOptions<E>) => Promise<T[]>;
341
- partitionAll: <T>(results: Array<TryoResult<T, E>>) => {
342
- ok: Array<SuccessResult<T, E>>;
343
- errors: Array<FailureResult<E> | AbortedResult<E> | TimeoutResult<E>>;
344
- failure: Array<FailureResult<E>>;
345
- aborted: Array<AbortedResult<E>>;
346
- timeout: Array<TimeoutResult<E>>;
347
- };
351
+ }) => MaybePromise<T>>, options?: AllOptions<E, T>) => Promise<T[]>;
352
+ partitionAll: <T>(results: Array<TryoResult<T, E>>) => PartitionedResults<T, E>;
348
353
  withConfig: (additionalConfig: Omit<Partial<TryoConfig<E>>, 'signal'>) => Tryo<E>;
349
354
  };
350
355
 
351
356
  declare const run: <T>(task: (ctx: {
352
357
  signal: AbortSignal;
353
- }) => T | Promise<T>, options?: {
354
- readonly timeout?: number | undefined;
355
- readonly signal?: AbortSignal | undefined;
356
- readonly ignoreAbort?: boolean | undefined;
357
- readonly retry?: RetryConfig<DefaultError> | undefined;
358
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
359
- readonly concurrency?: number | undefined;
360
- readonly logger?: LoggerConfig<DefaultError> | undefined;
361
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
362
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
363
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
364
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
365
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
366
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
367
- } | undefined) => Promise<TryoResult<T, DefaultError>>;
358
+ }) => T | Promise<T>, options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
359
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
360
+ }) | undefined) => Promise<TryoResult<T, DefaultError>>;
368
361
  declare const runOrThrow: <T>(task: (ctx: {
369
362
  signal: AbortSignal;
370
- }) => T | Promise<T>, options?: {
371
- readonly timeout?: number | undefined;
372
- readonly signal?: AbortSignal | undefined;
373
- readonly ignoreAbort?: boolean | undefined;
374
- readonly retry?: RetryConfig<DefaultError> | undefined;
375
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
376
- readonly concurrency?: number | undefined;
377
- readonly logger?: LoggerConfig<DefaultError> | undefined;
378
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
379
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
380
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
381
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
382
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
383
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
384
- } | undefined) => Promise<T>;
363
+ }) => T | Promise<T>, options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
364
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
365
+ }) | undefined) => Promise<T>;
385
366
  declare const orThrow: <T>(task: (ctx: {
386
367
  signal: AbortSignal;
387
- }) => T | Promise<T>, options?: {
388
- readonly timeout?: number | undefined;
389
- readonly signal?: AbortSignal | undefined;
390
- readonly ignoreAbort?: boolean | undefined;
391
- readonly retry?: RetryConfig<DefaultError> | undefined;
392
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
393
- readonly concurrency?: number | undefined;
394
- readonly logger?: LoggerConfig<DefaultError> | undefined;
395
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
396
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
397
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
398
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
399
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
400
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
401
- } | undefined) => Promise<T>;
368
+ }) => T | Promise<T>, options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
369
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
370
+ }) | undefined) => Promise<T>;
402
371
  declare const all: <T>(tasks: ((ctx: {
403
372
  signal: AbortSignal;
404
- }) => T | Promise<T>)[], options?: {
405
- readonly timeout?: number | undefined;
406
- readonly signal?: AbortSignal | undefined;
407
- readonly ignoreAbort?: boolean | undefined;
408
- readonly retry?: RetryConfig<DefaultError> | undefined;
409
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
410
- concurrency?: number | undefined;
411
- readonly logger?: LoggerConfig<DefaultError> | undefined;
412
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
413
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
414
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
415
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
416
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
417
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
418
- } | undefined) => Promise<TryoResult<T, DefaultError>[]>;
373
+ }) => T | Promise<T>)[], options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
374
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
375
+ }) | undefined) => Promise<TryoResult<T, DefaultError>[]>;
419
376
  declare const allOrThrow: <T>(tasks: ((ctx: {
420
377
  signal: AbortSignal;
421
- }) => T | Promise<T>)[], options?: {
422
- readonly timeout?: number | undefined;
423
- readonly signal?: AbortSignal | undefined;
424
- readonly ignoreAbort?: boolean | undefined;
425
- readonly retry?: RetryConfig<DefaultError> | undefined;
426
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
427
- concurrency?: number | undefined;
428
- readonly logger?: LoggerConfig<DefaultError> | undefined;
429
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
430
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
431
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
432
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
433
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
434
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
435
- } | undefined) => Promise<T[]>;
378
+ }) => T | Promise<T>)[], options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
379
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
380
+ }) | undefined) => Promise<T[]>;
436
381
 
437
382
  /**
438
383
  * Modern fluent error rule builder
@@ -497,4 +442,4 @@ declare const errorRule: {
497
442
  };
498
443
  };
499
444
 
500
- export { type AbortedResult, type FailureResult, type Milliseconds, type RetryCount, RetryStrategies, type RulesMode, type SuccessResult, type TimeoutResult, type TryoConfig, type TryoMetrics$1 as TryoMetrics, type TryoOptions, type TryoResult, TypedError, all, allOrThrow, asMilliseconds, asRetryCount, tryo as default, errorRule, orThrow, run, runOrThrow, tryo };
445
+ export { type AbortedResult, type FailureResult, type Milliseconds, type RetryCount, RetryStrategies, type RulesMode, type SuccessResult, type TimeoutResult, type TryoConfig, type TryoMetrics, type TryoOptions, type TryoResult, TypedError, all, allOrThrow, asMilliseconds, asRetryCount, tryo as default, errorRule, orThrow, run, runOrThrow, tryo };
package/dist/index.d.ts CHANGED
@@ -111,6 +111,46 @@ interface CircuitBreakerConfig<E extends AnyTypedError = AnyTypedError> {
111
111
  }
112
112
  type CircuitState = 'closed' | 'open' | 'half-open';
113
113
 
114
+ /**
115
+ * Modern error normalization system
116
+ * Provides type-safe error transformation and normalization
117
+ */
118
+
119
+ type ErrorNormalizer<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E;
120
+ type ErrorRule<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E | null;
121
+
122
+ /**
123
+ * Modern retry strategies with enhanced capabilities
124
+ * Provides various retry patterns with type safety
125
+ */
126
+
127
+ type RetryStrategy = FixedDelayStrategy | ExponentialBackoffStrategy | FibonacciBackoffStrategy | CustomDelayStrategy;
128
+ interface FixedDelayStrategy {
129
+ readonly type: 'fixed';
130
+ readonly delay: number;
131
+ }
132
+ interface ExponentialBackoffStrategy {
133
+ readonly type: 'exponential';
134
+ readonly base: number;
135
+ readonly factor: number;
136
+ readonly maxDelay?: number;
137
+ }
138
+ interface FibonacciBackoffStrategy {
139
+ readonly type: 'fibonacci';
140
+ readonly base: number;
141
+ readonly maxDelay?: number;
142
+ }
143
+ interface CustomDelayStrategy {
144
+ readonly type: 'custom';
145
+ readonly calculate: (attempt: RetryCount, error: unknown) => number;
146
+ }
147
+ declare const RetryStrategies: {
148
+ readonly fixed: (delay: number) => FixedDelayStrategy;
149
+ readonly exponential: (base: number, factor?: number, maxDelay?: number) => ExponentialBackoffStrategy;
150
+ readonly fibonacci: (base: number, maxDelay?: number) => FibonacciBackoffStrategy;
151
+ readonly custom: (calculate: (attempt: RetryCount, error: unknown) => number) => CustomDelayStrategy;
152
+ };
153
+
114
154
  /**
115
155
  * Modern result types with enhanced discriminated unions
116
156
  * Provides better type safety and more granular result categorization
@@ -122,30 +162,30 @@ interface SuccessResult<T, E extends AnyTypedError> {
122
162
  readonly ok: true;
123
163
  readonly data: T;
124
164
  readonly error: null;
125
- readonly metrics: TryoMetrics$1<E>;
165
+ readonly metrics: TryoMetrics<E>;
126
166
  }
127
167
  interface FailureResult<E extends AnyTypedError> {
128
168
  readonly type: 'failure';
129
169
  readonly ok: false;
130
170
  readonly data: null;
131
171
  readonly error: E;
132
- readonly metrics: TryoMetrics$1<E>;
172
+ readonly metrics: TryoMetrics<E>;
133
173
  }
134
174
  interface AbortedResult<E extends AnyTypedError> {
135
175
  readonly type: 'aborted';
136
176
  readonly ok: false;
137
177
  readonly data: null;
138
178
  readonly error: E;
139
- readonly metrics: TryoMetrics$1<E>;
179
+ readonly metrics: TryoMetrics<E>;
140
180
  }
141
181
  interface TimeoutResult<E extends AnyTypedError> {
142
182
  readonly type: 'timeout';
143
183
  readonly ok: false;
144
184
  readonly data: null;
145
185
  readonly error: E;
146
- readonly metrics: TryoMetrics$1<E>;
186
+ readonly metrics: TryoMetrics<E>;
147
187
  }
148
- interface TryoMetrics$1<E extends AnyTypedError> {
188
+ interface TryoMetrics<E extends AnyTypedError> {
149
189
  readonly totalAttempts: RetryCount;
150
190
  readonly totalRetries: RetryCount;
151
191
  readonly totalDuration: Milliseconds;
@@ -159,45 +199,10 @@ interface TryoMetrics$1<E extends AnyTypedError> {
159
199
  }
160
200
 
161
201
  /**
162
- * Modern error normalization system
163
- * Provides type-safe error transformation and normalization
164
- */
165
-
166
- type ErrorNormalizer<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E;
167
- type ErrorRule<E extends AnyTypedError = AnyTypedError> = (error: unknown) => E | null;
168
-
169
- /**
170
- * Modern retry strategies with enhanced capabilities
171
- * Provides various retry patterns with type safety
202
+ * Configuration types for modern execution engine
203
+ * Provides comprehensive configuration with type safety
172
204
  */
173
205
 
174
- type RetryStrategy = FixedDelayStrategy | ExponentialBackoffStrategy | FibonacciBackoffStrategy | CustomDelayStrategy;
175
- interface FixedDelayStrategy {
176
- readonly type: 'fixed';
177
- readonly delay: number;
178
- }
179
- interface ExponentialBackoffStrategy {
180
- readonly type: 'exponential';
181
- readonly base: number;
182
- readonly factor: number;
183
- readonly maxDelay?: number;
184
- }
185
- interface FibonacciBackoffStrategy {
186
- readonly type: 'fibonacci';
187
- readonly base: number;
188
- readonly maxDelay?: number;
189
- }
190
- interface CustomDelayStrategy {
191
- readonly type: 'custom';
192
- readonly calculate: (attempt: RetryCount, error: unknown) => number;
193
- }
194
- declare const RetryStrategies: {
195
- readonly fixed: (delay: number) => FixedDelayStrategy;
196
- readonly exponential: (base: number, factor?: number, maxDelay?: number) => ExponentialBackoffStrategy;
197
- readonly fibonacci: (base: number, maxDelay?: number) => FibonacciBackoffStrategy;
198
- readonly custom: (calculate: (attempt: RetryCount, error: unknown) => number) => CustomDelayStrategy;
199
- };
200
-
201
206
  interface TryoConfig<E extends AnyTypedError = AnyTypedError> {
202
207
  /** Abort signal passed to tasks */
203
208
  readonly signal?: AbortSignal;
@@ -265,7 +270,6 @@ interface LoggerConfig<E extends AnyTypedError> {
265
270
  /** Warning logging function */
266
271
  readonly warn?: (message: string, meta?: unknown) => void;
267
272
  }
268
- type TryoMetrics<E extends AnyTypedError> = TryoMetrics$1<E>;
269
273
  type JitterConfig = {
270
274
  type: 'none';
271
275
  } | {
@@ -287,10 +291,17 @@ declare const JitterConfig: {
287
291
 
288
292
  type RulesMode = 'extend' | 'replace';
289
293
  type DefaultError = AbortedError | TimeoutError | NetworkError | HttpError | CircuitOpenError | ValidationError | UnknownError;
290
- type RunOptions<E extends AnyTypedError> = Omit<Partial<TryoConfig<E>>, 'circuitBreaker'>;
291
- type AllOptions<E extends AnyTypedError> = Omit<Partial<TryoConfig<E> & {
292
- concurrency?: number;
293
- }>, 'circuitBreaker'>;
294
+ type RunOptions<E extends AnyTypedError, TData = unknown> = Omit<Partial<TryoConfig<E>>, 'circuitBreaker' | 'onSuccess'> & {
295
+ onSuccess?: (data: TData, metrics?: TryoMetrics<E>) => void;
296
+ };
297
+ type AllOptions<E extends AnyTypedError, TData = unknown> = RunOptions<E, TData>;
298
+ type PartitionedResults<T, E extends AnyTypedError> = {
299
+ ok: Array<SuccessResult<T, E>>;
300
+ errors: Array<FailureResult<E> | AbortedResult<E> | TimeoutResult<E>>;
301
+ failure: Array<FailureResult<E>>;
302
+ aborted: Array<AbortedResult<E>>;
303
+ timeout: Array<TimeoutResult<E>>;
304
+ };
294
305
  type MaybePromise<T> = T | Promise<T>;
295
306
  type RuleLike = (error: unknown) => AnyTypedError | null;
296
307
  type NonNull<T> = T extends null ? never : T;
@@ -325,114 +336,48 @@ declare function tryo<E extends AnyTypedError = DefaultError>(options?: TryoOpti
325
336
  type Tryo<E extends AnyTypedError = AnyTypedError> = {
326
337
  run: <T>(task: (ctx: {
327
338
  signal: AbortSignal;
328
- }) => MaybePromise<T>, options?: RunOptions<E>) => Promise<TryoResult<T, E>>;
339
+ }) => MaybePromise<T>, options?: RunOptions<E, T>) => Promise<TryoResult<T, E>>;
329
340
  runOrThrow: <T>(task: (ctx: {
330
341
  signal: AbortSignal;
331
- }) => MaybePromise<T>, options?: RunOptions<E>) => Promise<T>;
342
+ }) => MaybePromise<T>, options?: RunOptions<E, T>) => Promise<T>;
332
343
  orThrow: <T>(task: (ctx: {
333
344
  signal: AbortSignal;
334
- }) => MaybePromise<T>, options?: RunOptions<E>) => Promise<T>;
345
+ }) => MaybePromise<T>, options?: RunOptions<E, T>) => Promise<T>;
335
346
  all: <T>(tasks: Array<(ctx: {
336
347
  signal: AbortSignal;
337
- }) => MaybePromise<T>>, options?: AllOptions<E>) => Promise<Array<TryoResult<T, E>>>;
348
+ }) => MaybePromise<T>>, options?: AllOptions<E, T>) => Promise<Array<TryoResult<T, E>>>;
338
349
  allOrThrow: <T>(tasks: Array<(ctx: {
339
350
  signal: AbortSignal;
340
- }) => MaybePromise<T>>, options?: AllOptions<E>) => Promise<T[]>;
341
- partitionAll: <T>(results: Array<TryoResult<T, E>>) => {
342
- ok: Array<SuccessResult<T, E>>;
343
- errors: Array<FailureResult<E> | AbortedResult<E> | TimeoutResult<E>>;
344
- failure: Array<FailureResult<E>>;
345
- aborted: Array<AbortedResult<E>>;
346
- timeout: Array<TimeoutResult<E>>;
347
- };
351
+ }) => MaybePromise<T>>, options?: AllOptions<E, T>) => Promise<T[]>;
352
+ partitionAll: <T>(results: Array<TryoResult<T, E>>) => PartitionedResults<T, E>;
348
353
  withConfig: (additionalConfig: Omit<Partial<TryoConfig<E>>, 'signal'>) => Tryo<E>;
349
354
  };
350
355
 
351
356
  declare const run: <T>(task: (ctx: {
352
357
  signal: AbortSignal;
353
- }) => T | Promise<T>, options?: {
354
- readonly timeout?: number | undefined;
355
- readonly signal?: AbortSignal | undefined;
356
- readonly ignoreAbort?: boolean | undefined;
357
- readonly retry?: RetryConfig<DefaultError> | undefined;
358
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
359
- readonly concurrency?: number | undefined;
360
- readonly logger?: LoggerConfig<DefaultError> | undefined;
361
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
362
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
363
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
364
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
365
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
366
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
367
- } | undefined) => Promise<TryoResult<T, DefaultError>>;
358
+ }) => T | Promise<T>, options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
359
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
360
+ }) | undefined) => Promise<TryoResult<T, DefaultError>>;
368
361
  declare const runOrThrow: <T>(task: (ctx: {
369
362
  signal: AbortSignal;
370
- }) => T | Promise<T>, options?: {
371
- readonly timeout?: number | undefined;
372
- readonly signal?: AbortSignal | undefined;
373
- readonly ignoreAbort?: boolean | undefined;
374
- readonly retry?: RetryConfig<DefaultError> | undefined;
375
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
376
- readonly concurrency?: number | undefined;
377
- readonly logger?: LoggerConfig<DefaultError> | undefined;
378
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
379
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
380
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
381
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
382
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
383
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
384
- } | undefined) => Promise<T>;
363
+ }) => T | Promise<T>, options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
364
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
365
+ }) | undefined) => Promise<T>;
385
366
  declare const orThrow: <T>(task: (ctx: {
386
367
  signal: AbortSignal;
387
- }) => T | Promise<T>, options?: {
388
- readonly timeout?: number | undefined;
389
- readonly signal?: AbortSignal | undefined;
390
- readonly ignoreAbort?: boolean | undefined;
391
- readonly retry?: RetryConfig<DefaultError> | undefined;
392
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
393
- readonly concurrency?: number | undefined;
394
- readonly logger?: LoggerConfig<DefaultError> | undefined;
395
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
396
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
397
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
398
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
399
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
400
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
401
- } | undefined) => Promise<T>;
368
+ }) => T | Promise<T>, options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
369
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
370
+ }) | undefined) => Promise<T>;
402
371
  declare const all: <T>(tasks: ((ctx: {
403
372
  signal: AbortSignal;
404
- }) => T | Promise<T>)[], options?: {
405
- readonly timeout?: number | undefined;
406
- readonly signal?: AbortSignal | undefined;
407
- readonly ignoreAbort?: boolean | undefined;
408
- readonly retry?: RetryConfig<DefaultError> | undefined;
409
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
410
- concurrency?: number | undefined;
411
- readonly logger?: LoggerConfig<DefaultError> | undefined;
412
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
413
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
414
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
415
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
416
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
417
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
418
- } | undefined) => Promise<TryoResult<T, DefaultError>[]>;
373
+ }) => T | Promise<T>)[], options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
374
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
375
+ }) | undefined) => Promise<TryoResult<T, DefaultError>[]>;
419
376
  declare const allOrThrow: <T>(tasks: ((ctx: {
420
377
  signal: AbortSignal;
421
- }) => T | Promise<T>)[], options?: {
422
- readonly timeout?: number | undefined;
423
- readonly signal?: AbortSignal | undefined;
424
- readonly ignoreAbort?: boolean | undefined;
425
- readonly retry?: RetryConfig<DefaultError> | undefined;
426
- readonly errorHandling?: ErrorHandlingConfig<DefaultError> | undefined;
427
- concurrency?: number | undefined;
428
- readonly logger?: LoggerConfig<DefaultError> | undefined;
429
- readonly onSuccess?: (<T_1>(data: T_1, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
430
- readonly onError?: ((error: DefaultError, metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
431
- readonly onFinally?: ((metrics?: TryoMetrics$1<DefaultError> | undefined) => void) | undefined;
432
- readonly onAbort?: ((signal: AbortSignal) => void) | undefined;
433
- readonly onRetry?: ((attempt: number, error: DefaultError, delay: number) => void) | undefined;
434
- readonly onCircuitStateChange?: ((from: CircuitState, to: CircuitState) => void) | undefined;
435
- } | undefined) => Promise<T[]>;
378
+ }) => T | Promise<T>)[], options?: (Omit<Partial<TryoConfig<DefaultError>>, "circuitBreaker" | "onSuccess"> & {
379
+ onSuccess?: ((data: T, metrics?: TryoMetrics<DefaultError> | undefined) => void) | undefined;
380
+ }) | undefined) => Promise<T[]>;
436
381
 
437
382
  /**
438
383
  * Modern fluent error rule builder
@@ -497,4 +442,4 @@ declare const errorRule: {
497
442
  };
498
443
  };
499
444
 
500
- export { type AbortedResult, type FailureResult, type Milliseconds, type RetryCount, RetryStrategies, type RulesMode, type SuccessResult, type TimeoutResult, type TryoConfig, type TryoMetrics$1 as TryoMetrics, type TryoOptions, type TryoResult, TypedError, all, allOrThrow, asMilliseconds, asRetryCount, tryo as default, errorRule, orThrow, run, runOrThrow, tryo };
445
+ export { type AbortedResult, type FailureResult, type Milliseconds, type RetryCount, RetryStrategies, type RulesMode, type SuccessResult, type TimeoutResult, type TryoConfig, type TryoMetrics, type TryoOptions, type TryoResult, TypedError, all, allOrThrow, asMilliseconds, asRetryCount, tryo as default, errorRule, orThrow, run, runOrThrow, tryo };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var de=Object.defineProperty;var ye=(e,r,t)=>r in e?de(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var l=(e,r,t)=>ye(e,typeof r!="symbol"?r+"":r,t);var f=class extends Error{constructor(t,n){var o,a;super(t);l(this,"cause");l(this,"title");l(this,"meta");l(this,"status");l(this,"raw");l(this,"path");l(this,"timestamp");l(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=(a=n.meta)!=null?a:{},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}}},F=class extends f{constructor(t,n){super(`Operation timed out after ${t}ms`,{cause:n,retryable:!0});l(this,"code","TIMEOUT")}};var B=class extends f{constructor(t,n){super(`Circuit breaker is open, reset after ${t}ms`,{cause:n,retryable:!1});l(this,"code","CIRCUIT_OPEN")}};var _=class extends f{constructor(t,n){super(t,{cause:n});l(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},x=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 U=class{constructor(r){l(this,"state");l(this,"config");this.config={failureThreshold:x(r.failureThreshold),resetTimeout:b(r.resetTimeout),halfOpenRequests:x(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,a,s;if(!((s=(a=(o=this.config).shouldCountAsFailure)==null?void 0:a.call(o,r))!=null?s:!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 B(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 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,L=class{constructor(r){this.predicate=r}toCode(r){return new K(this.predicate,r)}toError(r){return t=>{var c;if(!this.predicate(t))return null;let n=r(t),o=n.code,a=Object.hasOwn(n,"cause")?n.cause:t,s=(c=n.meta)!=null?c:{};class i extends f{constructor(){let y=Object.hasOwn(n,"raw")?n.raw:t;super(n.message,{title:n.title,cause:a,meta:s,status:n.status,retryable:n.retryable,raw:y,path:n.path});l(this,"code",o)}}return new i}}};function we(e,r){let t=new L(a=>a instanceof e);if(r)return t.toError(r);let o=a=>{if(!(a instanceof e))return null;if(a instanceof f)return a;let s=a,i=typeof s.code=="string"&&s.code.length>0?s.code:"UNKNOWN",c=Object.hasOwn(s,"cause"),u=Object.hasOwn(s,"raw");class d extends f{constructor(){super(s.message||i,{title:typeof s.title=="string"?s.title:void 0,cause:c?s.cause:a,meta:Ee(s.meta)?s.meta:{},status:typeof s.status=="number"?s.status:void 0,retryable:typeof s.retryable=="boolean"?s.retryable:void 0,raw:u?s.raw:a,path:typeof s.path=="string"?s.path:void 0});l(this,"code",i)}}return new d};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){return t=>{var c;if(!this.predicate(t))return null;let n=r(t),o=Object.hasOwn(n,"cause")?n.cause:t,a=(c=n.meta)!=null?c:{},s=this.errorCode;class i extends f{constructor(){let T=Object.hasOwn(n,"raw")?n.raw:t;super(n.message,{title:n.title,cause:o,meta:a,status:n.status,retryable:n.retryable,raw:T,path:n.path});l(this,"code",s)}}return new i}}},h={when:e=>new L(e),instance:we},g={typed:(e=>e instanceof f?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 f)).toCode("UNKNOWN").with(e=>({message:e.message||"Unknown error occurred",cause:e,raw:e}))};var Te=[g.typed,g.abort,g.timeout,g.http,g.network,g.unknown];var be={when:e=>h.when(e),instance:h.instance},re=Te;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})},te=(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},ne=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 oe=(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)},a,s=()=>{a&&clearTimeout(a),o(s),n(new DOMException("Aborted","AbortError"))};a=setTimeout(()=>{o(s),t()},e),r==null||r.addEventListener("abort",s,{once:!0})}),se=(e,r,t,n)=>new Promise((o,a)=>{if(t!=null&&t.aborted){a(new DOMException("Aborted","AbortError"));return}let s=!1,i=setTimeout(()=>{var d;s=!0,u(),a((d=n==null?void 0:n())!=null?d:new Error(`Operation timed out after ${r}ms`))},r),c=()=>{s||(s=!0,u(),a(new DOMException("Aborted","AbortError")))},u=()=>{clearTimeout(i),t==null||t.removeEventListener("abort",c)};t==null||t.addEventListener("abort",c,{once:!0}),e.then(d=>{s||(s=!0,u(),o(d))},d=>{s||(s=!0,u(),a(d))})});var Ce=e=>{var s,i,c;if(e.toError)return e.toError;let r=(s=e.rulesMode)!=null?s:"extend",t=(i=e.rules)!=null?i:[],n=re,o=(c=e.fallback)!=null?c:(u=>ee(_)(u)),a=r==="replace"?t:[...t,...n];return Z(a,o)},xe=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&&(ne(r.retry.strategy),xe(r.retry.jitter),r={...r,retry:{...r.retry,maxRetries:Number(x(r.retry.maxRetries))}}),r},J=class e{constructor(r={}){l(this,"circuitBreaker");l(this,"config");l(this,"lastCircuitState");let{rules:t,rulesMode:n,fallback:o,toError:a,mapError:s,...i}=r,c=Ce(r),u={...i,errorHandling:{normalizer:c,mapError:s}};this.config=V(u),u.circuitBreaker&&(this.circuitBreaker=new U(u.circuitBreaker),this.lastCircuitState=this.circuitBreaker.getState().state)}async run(r,t={}){var a,s,i,c;let n=V({...this.config,...t});if(this.circuitBreaker){let u=(a=this.lastCircuitState)!=null?a:this.circuitBreaker.getState().state,d=await this.circuitBreaker.canExecute(),y=this.circuitBreaker.getState().state;if(u!==y)try{(s=n.onCircuitStateChange)==null||s.call(n,u,y)}catch{}if(this.lastCircuitState=y,!d)return{type:"failure",ok:!1,data:null,error:this.circuitBreaker.createOpenError(),metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,retryHistory:[]}}}let o=await ge(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 d=this.circuitBreaker.getState().state;if(u!==d)try{(c=n.onCircuitStateChange)==null||c.call(n,u,d)}catch{}this.lastCircuitState=d}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 d;let n=V({...this.config,...t}),o=(d=n.concurrency)!=null?d:Number.POSITIVE_INFINITY,a=Number.isFinite(o)?Number(W(o)):Number.POSITIVE_INFINITY;if(a===Number.POSITIVE_INFINITY)return Promise.all(r.map(y=>this.run(y,n)));let s=new Array(r.length),i=0,c=async()=>{var y;for(;i<r.length&&!((y=n.signal)!=null&&y.aborted);){let T=i++;if(T>=r.length)break;let E=r[T];E&&(s[T]=await this.run(E,n))}},u=Array.from({length:Math.min(a,r.length)},()=>c());await Promise.all(u);for(let y=0;y<r.length;y++)if(!(y in s)){let T=r[y];T&&(s[y]=await this.run(T,n))}return s}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=[],a=[],s=[];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":a.push(i);break;case"timeout":s.push(i);break}}return{ok:t,errors:n,failure:o,aborted:a,timeout:s}}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 c,u;let{errorHandling:t,...n}=this.config,{errorHandling:o,...a}=r,s=(c=o==null?void 0:o.normalizer)!=null?c:t.normalizer,i=(u=o==null?void 0:o.mapError)!=null?u:t.mapError;return new e({...n,...a,toError:s,mapError:i})}};function z(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 ge(e,r){let{signal:t,ignoreAbort:n=!0,timeout:o,retry:a,errorHandling:s,logger:i,onSuccess:c,onError:u,onFinally:d,onAbort:y,onRetry:T}=r,E=(C,...p)=>{try{C==null||C(...p)}catch{}},N,k=0,H=0,R=[],M=Date.now(),{signal:I,cleanup:ie}=ae(t),v=C=>({totalAttempts:k,totalRetries:k>0?Number(k)-1:0,totalDuration:Date.now()-M,lastError:C,retryHistory:R});try{if(I.aborted){E(y,I);let p=s.normalizer(new DOMException("Aborted","AbortError")),w=s.mapError?s.mapError(p):p;return{type:"aborted",ok:!1,data:null,error:w,metrics:{totalAttempts:k,totalRetries:H,totalDuration:Date.now()-M,lastError:w,retryHistory:R}}}let C=async()=>{var D,O,j;let p=1,w=x((D=a==null?void 0:a.maxRetries)!=null?D:0);for(;;){k=p;let Y=new AbortController,{signal:q,cleanup:ue}=ae(I,Y.signal);try{let P=Promise.resolve(e({signal:q})),A=o?await se(P,o,q,()=>(Y.abort(),new F(b(o)))):await P;return E(c,A,v()),E(i==null?void 0:i.info,`Task succeeded on attempt ${p}`),A}catch(P){let A=s.normalizer(P),m=s.mapError?s.mapError(A):A;if(N=m,m.code==="ABORTED"&&E(y,q),n&&m.code==="ABORTED"||(E(u,m,v(m)),E(i==null?void 0:i.error,`Task failed on attempt ${p}`,m)),m.code==="ABORTED"||m.retryable===!1)throw m;if(p<=Number(w)){let G=a==null?void 0:a.shouldRetry,ce={totalAttempts:Number(k),elapsedTime:Date.now()-M,startTime:new Date(M),lastDelay:(O=R[R.length-1])!=null&&O.delay?Number((j=R[R.length-1])==null?void 0:j.delay):void 0};if(!G||G(p,m,ce)){let le=a?te(a.strategy,p,m):0,$=ke(le,a==null?void 0:a.jitter),Q=b($);R.push({attempt:p,error:m,delay:Q,timestamp:new Date}),E(T,p,m,$),E(i==null?void 0:i.info,`Retrying in ${$}ms (attempt ${p+1})`),p+=1,await oe(Q,I);continue}}throw m}finally{ue()}}};try{let p=await C(),w=v();return H=w.totalRetries,E(d,w),{type:"success",ok:!0,data:p,error:null,metrics:w}}catch(p){let w=N!=null?N:s.normalizer(p),D=w.code==="TIMEOUT"?"timeout":w.code==="ABORTED"?"aborted":"failure",O=v(w);return H=O.totalRetries,E(d,O),{type:D,ok:!1,data:null,error:w,metrics:O}}}finally{ie()}}function ae(...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 a=()=>r.abort();o.addEventListener("abort",a,{once:!0}),n.push({signal:o,abort:a})}return{signal:r.signal,cleanup:()=>{for(let o of n)o.signal.removeEventListener("abort",o.abort)}}}function ke(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 S=z(),Oe=S.run,Ae=S.runOrThrow,Se=S.orThrow,Ne=S.all,Me=S.allOrThrow;export{he as RetryStrategies,f as TypedError,Ne as all,Me as allOrThrow,b as asMilliseconds,x as asRetryCount,z as default,be as errorRule,Se as orThrow,Oe as run,Ae as runOrThrow,z as tryo};
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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tryo",
3
- "version": "0.13.8",
3
+ "version": "0.13.9",
4
4
  "author": {
5
5
  "name": "sebasxsala",
6
6
  "url": "https://github.com/sebasxsala"