awaitly 1.34.0 → 2.0.0
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/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
- package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
- package/dist/errors-DtXvrCiO.d.cts +708 -0
- package/dist/errors-DtXvrCiO.d.ts +708 -0
- package/dist/index.cjs +4594 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1970 -141
- package/dist/index.d.ts +1970 -141
- package/dist/index.js +4398 -1
- package/dist/index.js.map +1 -1
- package/dist/result.cjs +641 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +35 -5
- package/dist/result.d.ts +35 -5
- package/dist/result.js +561 -1
- package/dist/result.js.map +1 -1
- package/dist/testing.cjs +4202 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -6
- package/dist/testing.d.ts +2 -6
- package/dist/testing.js +4154 -8
- package/dist/testing.js.map +1 -1
- package/dist/{run-entry-D2MmJFj9.d.cts → types-B8NfNRGX.d.ts} +1152 -1499
- package/dist/{run-entry-Dduz-is2.d.ts → types-BZ2f4MRR.d.cts} +1152 -1499
- package/dist/workflow.cjs +7096 -6
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3346 -22
- package/dist/workflow.d.ts +3346 -22
- package/dist/workflow.js +6929 -6
- package/dist/workflow.js.map +1 -1
- package/package.json +13 -178
- package/dist/adapters.cjs +0 -7
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.d.cts +0 -179
- package/dist/adapters.d.ts +0 -179
- package/dist/adapters.js +0 -7
- package/dist/adapters.js.map +0 -1
- package/dist/batch.cjs +0 -7
- package/dist/batch.cjs.map +0 -1
- package/dist/batch.d.cts +0 -200
- package/dist/batch.d.ts +0 -200
- package/dist/batch.js +0 -7
- package/dist/batch.js.map +0 -1
- package/dist/bind-deps.cjs +0 -2
- package/dist/bind-deps.cjs.map +0 -1
- package/dist/bind-deps.d.cts +0 -28
- package/dist/bind-deps.d.ts +0 -28
- package/dist/bind-deps.js +0 -2
- package/dist/bind-deps.js.map +0 -1
- package/dist/cache.cjs +0 -2
- package/dist/cache.cjs.map +0 -1
- package/dist/cache.d.cts +0 -269
- package/dist/cache.d.ts +0 -269
- package/dist/cache.js +0 -2
- package/dist/cache.js.map +0 -1
- package/dist/circuit-breaker.cjs +0 -7
- package/dist/circuit-breaker.cjs.map +0 -1
- package/dist/circuit-breaker.d.cts +0 -211
- package/dist/circuit-breaker.d.ts +0 -211
- package/dist/circuit-breaker.js +0 -7
- package/dist/circuit-breaker.js.map +0 -1
- package/dist/conditional.cjs +0 -2
- package/dist/conditional.cjs.map +0 -1
- package/dist/conditional.d.cts +0 -252
- package/dist/conditional.d.ts +0 -252
- package/dist/conditional.js +0 -2
- package/dist/conditional.js.map +0 -1
- package/dist/core.cjs +0 -7
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -5
- package/dist/core.d.ts +0 -5
- package/dist/core.js +0 -7
- package/dist/core.js.map +0 -1
- package/dist/di-COl5oFnR.d.cts +0 -15
- package/dist/di-CyDj_JyZ.d.ts +0 -15
- package/dist/diagnostics.cjs +0 -8
- package/dist/diagnostics.cjs.map +0 -1
- package/dist/diagnostics.d.cts +0 -68
- package/dist/diagnostics.d.ts +0 -68
- package/dist/diagnostics.js +0 -8
- package/dist/diagnostics.js.map +0 -1
- package/dist/durable.cjs +0 -11
- package/dist/durable.cjs.map +0 -1
- package/dist/durable.d.cts +0 -9
- package/dist/durable.d.ts +0 -9
- package/dist/durable.js +0 -11
- package/dist/durable.js.map +0 -1
- package/dist/duration.cjs +0 -2
- package/dist/duration.cjs.map +0 -1
- package/dist/duration.js +0 -2
- package/dist/duration.js.map +0 -1
- package/dist/engine.cjs +0 -11
- package/dist/engine.cjs.map +0 -1
- package/dist/engine.d.cts +0 -115
- package/dist/engine.d.ts +0 -115
- package/dist/engine.js +0 -11
- package/dist/engine.js.map +0 -1
- package/dist/errors.cjs +0 -2
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -361
- package/dist/errors.d.ts +0 -361
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +0 -1
- package/dist/fetch.cjs +0 -7
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.cts +0 -86
- package/dist/fetch.d.ts +0 -86
- package/dist/fetch.js +0 -7
- package/dist/fetch.js.map +0 -1
- package/dist/flow.cjs +0 -7
- package/dist/flow.cjs.map +0 -1
- package/dist/flow.d.cts +0 -163
- package/dist/flow.d.ts +0 -163
- package/dist/flow.js +0 -7
- package/dist/flow.js.map +0 -1
- package/dist/functional.cjs +0 -2
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.d.cts +0 -444
- package/dist/functional.d.ts +0 -444
- package/dist/functional.js +0 -2
- package/dist/functional.js.map +0 -1
- package/dist/guards-BodHXLzX.d.cts +0 -72
- package/dist/guards-CeWoQ8fn.d.ts +0 -72
- package/dist/hitl-BPE_1UiM.d.cts +0 -468
- package/dist/hitl-byp570uC.d.ts +0 -468
- package/dist/hitl.cjs +0 -7
- package/dist/hitl.cjs.map +0 -1
- package/dist/hitl.d.cts +0 -442
- package/dist/hitl.d.ts +0 -442
- package/dist/hitl.js +0 -7
- package/dist/hitl.js.map +0 -1
- package/dist/index-BYT3amEz.d.ts +0 -417
- package/dist/index-C_ak66jy.d.cts +0 -417
- package/dist/match-entry-DjI2bLpD.d.cts +0 -209
- package/dist/match-entry-DjI2bLpD.d.ts +0 -209
- package/dist/match.cjs +0 -2
- package/dist/match.cjs.map +0 -1
- package/dist/match.d.cts +0 -1
- package/dist/match.d.ts +0 -1
- package/dist/match.js +0 -2
- package/dist/match.js.map +0 -1
- package/dist/otel.cjs +0 -2
- package/dist/otel.cjs.map +0 -1
- package/dist/otel.d.cts +0 -188
- package/dist/otel.d.ts +0 -188
- package/dist/otel.js +0 -2
- package/dist/otel.js.map +0 -1
- package/dist/persistence-entry-DOMx3woy.d.ts +0 -822
- package/dist/persistence-entry-ymCA4iDu.d.cts +0 -822
- package/dist/persistence.cjs +0 -2
- package/dist/persistence.cjs.map +0 -1
- package/dist/persistence.d.cts +0 -7
- package/dist/persistence.d.ts +0 -7
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +0 -1
- package/dist/policies.cjs +0 -2
- package/dist/policies.cjs.map +0 -1
- package/dist/policies.d.cts +0 -379
- package/dist/policies.d.ts +0 -379
- package/dist/policies.js +0 -2
- package/dist/policies.js.map +0 -1
- package/dist/ratelimit.cjs +0 -7
- package/dist/ratelimit.cjs.map +0 -1
- package/dist/ratelimit.d.cts +0 -458
- package/dist/ratelimit.d.ts +0 -458
- package/dist/ratelimit.js +0 -7
- package/dist/ratelimit.js.map +0 -1
- package/dist/reliability.cjs +0 -11
- package/dist/reliability.cjs.map +0 -1
- package/dist/reliability.d.cts +0 -11
- package/dist/reliability.d.ts +0 -11
- package/dist/reliability.js +0 -11
- package/dist/reliability.js.map +0 -1
- package/dist/resolver.cjs +0 -7
- package/dist/resolver.cjs.map +0 -1
- package/dist/resolver.d.cts +0 -68
- package/dist/resolver.d.ts +0 -68
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/resource.cjs +0 -7
- package/dist/resource.cjs.map +0 -1
- package/dist/resource.d.cts +0 -174
- package/dist/resource.d.ts +0 -174
- package/dist/resource.js +0 -7
- package/dist/resource.js.map +0 -1
- package/dist/result/retry.cjs +0 -2
- package/dist/result/retry.cjs.map +0 -1
- package/dist/result/retry.d.cts +0 -70
- package/dist/result/retry.d.ts +0 -70
- package/dist/result/retry.js +0 -2
- package/dist/result/retry.js.map +0 -1
- package/dist/retry.cjs +0 -2
- package/dist/retry.cjs.map +0 -1
- package/dist/retry.d.cts +0 -388
- package/dist/retry.d.ts +0 -388
- package/dist/retry.js +0 -2
- package/dist/retry.js.map +0 -1
- package/dist/run.cjs +0 -7
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -4
- package/dist/run.d.ts +0 -4
- package/dist/run.js +0 -7
- package/dist/run.js.map +0 -1
- package/dist/saga.cjs +0 -11
- package/dist/saga.cjs.map +0 -1
- package/dist/saga.d.cts +0 -164
- package/dist/saga.d.ts +0 -164
- package/dist/saga.js +0 -11
- package/dist/saga.js.map +0 -1
- package/dist/singleflight.cjs +0 -2
- package/dist/singleflight.cjs.map +0 -1
- package/dist/singleflight.d.cts +0 -145
- package/dist/singleflight.d.ts +0 -145
- package/dist/singleflight.js +0 -2
- package/dist/singleflight.js.map +0 -1
- package/dist/slugs.cjs +0 -2
- package/dist/slugs.cjs.map +0 -1
- package/dist/slugs.d.cts +0 -67
- package/dist/slugs.d.ts +0 -67
- package/dist/slugs.js +0 -2
- package/dist/slugs.js.map +0 -1
- package/dist/streaming.cjs +0 -9
- package/dist/streaming.cjs.map +0 -1
- package/dist/streaming.d.cts +0 -596
- package/dist/streaming.d.ts +0 -596
- package/dist/streaming.js +0 -9
- package/dist/streaming.js.map +0 -1
- package/dist/tagged-error.cjs +0 -2
- package/dist/tagged-error.cjs.map +0 -1
- package/dist/tagged-error.d.cts +0 -275
- package/dist/tagged-error.d.ts +0 -275
- package/dist/tagged-error.js +0 -2
- package/dist/tagged-error.js.map +0 -1
- package/dist/types-DQmzO9f4.d.ts +0 -323
- package/dist/types-qBUOYi-4.d.cts +0 -323
- package/dist/webhook.cjs +0 -7
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts +0 -499
- package/dist/webhook.d.ts +0 -499
- package/dist/webhook.js +0 -7
- package/dist/webhook.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,4595 @@
|
|
|
1
|
-
"use strict";var L=Object.defineProperty;var We=Object.getOwnPropertyDescriptor;var Ye=Object.getOwnPropertyNames;var Je=Object.prototype.hasOwnProperty;var _e=(e,r)=>{for(var n in r)L(e,n,{get:r[n],enumerable:!0})},qe=(e,r,n,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of Ye(r))!Je.call(e,o)&&o!==n&&L(e,o,{get:()=>r[o],enumerable:!(t=We(r,o))||t.enumerable});return e};var Ze=e=>qe(L({},"__esModule",{value:!0}),e);var cr={};_e(cr,{AWAITLY_CANCELLED:()=>G,AWAITLY_TIMEOUT:()=>V,AWAITLY_UNEXPECTED:()=>z,Awaitly:()=>ir,DESERIALIZATION_ERROR:()=>y,PROMISE_REJECTED:()=>p,R:()=>N,TaggedError:()=>c,UnexpectedError:()=>C,UnwrapError:()=>R,all:()=>Re,allAsync:()=>ke,allSettled:()=>me,allSettledAsync:()=>ge,andThen:()=>ue,any:()=>we,anyAsync:()=>Ae,bimap:()=>le,compose:()=>O,deserialize:()=>ve,err:()=>u,flatMapAsync:()=>_,flatten:()=>Pe,flow:()=>U,from:()=>ee,fromNullable:()=>te,fromPromise:()=>re,getOrElse:()=>w,getOrElseLazy:()=>A,hydrate:()=>Ce,identity:()=>B,isErr:()=>f,isOk:()=>l,isPromiseRejectedError:()=>W,isSerializedResult:()=>ye,isUnexpectedError:()=>m,map:()=>oe,mapAsync:()=>D,mapError:()=>se,mapErrorTry:()=>Ee,mapTry:()=>ce,match:()=>P,matchError:()=>h,matchErrorPartial:()=>Ue,ok:()=>a,orElse:()=>pe,orElseAsync:()=>fe,partition:()=>xe,pipe:()=>b,race:()=>F,recover:()=>de,recoverAsync:()=>Te,recoverWith:()=>x,runOrNull:()=>X,runOrThrow:()=>q,runOrThrowAsync:()=>Z,runOrUndefined:()=>Q,serialize:()=>be,tags:()=>$,tap:()=>ae,tapAsync:()=>j,tapError:()=>ie,tapErrorAsync:()=>S,traverse:()=>I,traverseAsync:()=>H,traverseParallel:()=>K,tryAsync:()=>ne,unwrap:()=>g,unwrapOr:()=>Y,unwrapOrElse:()=>J,withDeps:()=>Be,zip:()=>v,zipAsync:()=>he});module.exports=Ze(cr);var Oe={};_e(Oe,{AWAITLY_CANCELLED:()=>G,AWAITLY_TIMEOUT:()=>V,AWAITLY_UNEXPECTED:()=>z,DESERIALIZATION_ERROR:()=>y,PROMISE_REJECTED:()=>p,UnexpectedError:()=>C,UnwrapError:()=>R,all:()=>Re,allAsync:()=>ke,allSettled:()=>me,allSettledAsync:()=>ge,andThen:()=>ue,any:()=>we,anyAsync:()=>Ae,bimap:()=>le,deserialize:()=>ve,err:()=>u,flatten:()=>Pe,from:()=>ee,fromNullable:()=>te,fromPromise:()=>re,hydrate:()=>Ce,isErr:()=>f,isOk:()=>l,isPromiseRejectedError:()=>W,isSerializedResult:()=>ye,isUnexpectedError:()=>m,map:()=>oe,mapError:()=>se,mapErrorTry:()=>Ee,mapTry:()=>ce,match:()=>P,matchError:()=>h,matchErrorPartial:()=>Ue,ok:()=>a,orElse:()=>pe,orElseAsync:()=>fe,partition:()=>xe,recover:()=>de,recoverAsync:()=>Te,runOrNull:()=>X,runOrThrow:()=>q,runOrThrowAsync:()=>Z,runOrUndefined:()=>Q,serialize:()=>be,tags:()=>$,tap:()=>ae,tapError:()=>ie,tryAsync:()=>ne,unwrap:()=>g,unwrapOr:()=>Y,unwrapOrElse:()=>J,zip:()=>v,zipAsync:()=>he});var Xe={"step-require-id":"step-require-id","step-no-immediate-execution":"step-no-immediate-execution","step-require-thunk-for-key":"step-require-thunk-for-key","step-no-bare-await":"step-no-bare-await","step-no-try-catch-wrap":"step-no-try-catch-wrap","step-stable-cache-keys":"step-stable-cache-keys","workflow-no-floating":"workflow-no-floating","workflow-options-position":"workflow-options-position","workflow-callback-shape":"workflow-callback-shape","workflow-no-callable-form":"workflow-no-callable-form","workflow-no-dynamic-import":"workflow-no-dynamic-import","result-no-floating":"result-no-floating","result-require-handling":"result-require-handling","result-no-double-wrap":"result-no-double-wrap","result-no-manual-propagation":"result-no-manual-propagation","result-no-direct-ok-err":"result-no-direct-ok-err","error-check-unexpected-first":"error-check-unexpected-first","error-access-cause":"error-access-cause","error-normalize":"error-normalize","error-no-throw-in-deps":"error-no-throw-in-deps","concurrency-no-promise-all":"concurrency-no-promise-all","concurrency-no-promise-race":"concurrency-no-promise-race","concurrency-no-promise-allsettled":"concurrency-no-promise-allsettled","runtime-step-timeout":"runtime-step-timeout","runtime-step-aborted":"runtime-step-aborted","runtime-retry-exhausted":"runtime-retry-exhausted","runtime-rate-limit":"runtime-rate-limit","runtime-circuit-open":"runtime-circuit-open","runtime-unexpected":"runtime-unexpected","runtime-resolver-not-found":"runtime-resolver-not-found","runtime-saga-compensation":"runtime-saga-compensation"};function je(e){return`https://jagreehal.github.io/awaitly/rules/#${e}`}var fr=Object.keys(Xe);var k=class extends Error{_tag};function c(e,r){return class extends k{_tag=e;constructor(n,t){let o=r?.message?r.message(n??{}):e;if(super(o),this.name=e,r?.slug!==void 0){if(!r.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${r.slug}")`);Object.defineProperty(this,"code",{value:r.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:r.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:je(r.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),n&&typeof n=="object"){let s;if(r?.slug!==void 0){let{_tag:T,name:M,message:Ge,stack:Ve,code:De,hint:Er,docsUrl:lr,...$e}=n;s=$e}else{let{_tag:T,name:M,message:Ge,stack:Ve,...De}=n;s=De}let i=Object.prototype.hasOwnProperty.call(s,"cause"),E=i?s.cause:void 0;i&&delete s.cause;let d=t?.cause!==void 0;if(i&&d)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,s),i&&(this.cause=E),d&&(this.cause=t?.cause)}else t?.cause!==void 0&&(this.cause=t.cause)}}}Object.defineProperty(c,Symbol.hasInstance,{value:e=>e instanceof k});(o=>{function e(s){return s instanceof Error}o.isError=e;function r(s){return s instanceof k}o.isTaggedError=r;function n(s,i){let E=s._tag,d=i[E];return d(s)}o.match=n;function t(s,i,E){let d=s._tag,T=i[d];return T?T(s):E(s)}o.matchPartial=t})(c||={});var Se=class extends c("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:r=>r.operation?`TimeoutError: ${r.operation} timed out after ${r.ms}ms`:`TimeoutError: Operation timed out after ${r.ms}ms`}){},Fe=class extends c("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:r=>r.operation?`RetryExhaustedError: ${r.operation} failed after ${r.attempts} attempts`:`RetryExhaustedError: Operation failed after ${r.attempts} attempts`}){},Ie=class extends c("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:r=>r.limiterName?`RateLimitError: Rate limit exceeded for ${r.limiterName}${r.retryAfterMs?`, retry after ${r.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${r.retryAfterMs?`, retry after ${r.retryAfterMs}ms`:""}`}){},He=class extends c("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:r=>`CircuitBreakerOpenError: Circuit ${r.circuitName} is ${r.state??"OPEN"}${r.retryAfterMs?`, retry after ${Math.ceil(r.retryAfterMs/1e3)}s`:""}`}){},Ke=class extends c("ValidationError",{message:r=>`ValidationError: Invalid ${r.field} - ${r.reason}`}){},Ne=class extends c("NotFoundError",{message:r=>r.id?`NotFoundError: ${r.resource} with id ${r.id} not found`:`NotFoundError: ${r.resource} not found`}){},Me=class extends c("UnauthorizedError",{message:r=>r.reason?`UnauthorizedError: ${r.reason}`:r.action&&r.resource?`UnauthorizedError: Not authorized to ${r.action} ${r.resource}`:"UnauthorizedError: Access denied"}){},Le=class extends c("NetworkError",{message:r=>r.url?`NetworkError: ${r.reason} (${r.url})`:`NetworkError: ${r.reason}`}){},ze=class extends c("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:r=>`CompensationError: Failed to compensate step ${r.step}`}){},C=class extends c("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:r=>`UnexpectedError: ${r.cause instanceof Error?r.cause.message:String(r.cause??"unknown")}`}){};var p="PROMISE_REJECTED",z="AWAITLY_UNEXPECTED",G="AWAITLY_CANCELLED",V="AWAITLY_TIMEOUT",$=(...e)=>e;function a(e){return{ok:!0,value:e}}function u(e,r){let n=r?.cause;return{ok:!1,error:e,...n!==void 0?{cause:n}:{}}}var l=e=>e.ok,f=e=>!e.ok,m=e=>e instanceof C||typeof e=="object"&&e!==null&&"_tag"in e&&e._tag==="UnexpectedError",W=e=>typeof e=="object"&&e!==null&&"type"in e&&e.type===p;function h(e,r){if(r===void 0){let t=e;return o=>h(o,t)}let n=e;return m(n)?r.UnexpectedError(n):r[n](n)}var R=class extends Error{error;cause;constructor(r){let n=typeof r.error=="string"?r.error:JSON.stringify(r.error);super(`Attempted to unwrap an Err: ${n}`),this.name="UnwrapError",this.error=r.error,this.cause=r.cause}},g=e=>{if(e.ok)return e.value;throw new R(e)},Y=(e,r)=>e.ok?e.value:r,J=(e,r)=>e.ok?e.value:r(e.error,e.cause),q=e=>g(e),Z=e=>Promise.resolve(e).then(g),X=e=>e.ok?e.value:null,Q=e=>e.ok?e.value:void 0;function ee(e,r){try{return a(e())}catch(n){return r?u(r(n),{cause:n}):u(n)}}async function re(e,r){try{return a(await e)}catch(n){return r?u(r(n),{cause:n}):u(n)}}async function ne(e,r){try{return a(await e())}catch(n){return r?u(r(n),{cause:n}):u(n)}}function te(e,r){return e!=null?a(e):u(r())}function oe(e,r){return e.ok?a(r(e.value)):e}function se(e,r){return e.ok?e:u(r(e.error,e.cause),{cause:e.cause})}function P(e,r){if(r===void 0){let n=e;return t=>P(t,n)}return e.ok?r.ok(e.value):r.err(e.error,e.cause)}function ue(e,r){return e.ok?r(e.value):e}function ae(e,r){return e.ok&&r(e.value),e}function ie(e,r){return e.ok||r(e.error,e.cause),e}function ce(e,r,n){if(!e.ok)return e;try{return a(r(e.value))}catch(t){return u(n(t),{cause:t})}}function Ee(e,r,n){if(e.ok)return e;try{return u(r(e.error),{cause:e.cause})}catch(t){return u(n(t),{cause:t})}}function le(e,r,n){return e.ok?a(r(e.value)):u(n(e.error,e.cause),{cause:e.cause})}function pe(e,r){return e.ok?e:r(e.error,e.cause)}async function fe(e,r){return e.ok?e:r(e.error,e.cause)}function de(e,r){return e.ok?a(e.value):a(r(e.error,e.cause))}async function Te(e,r){let n=await e;return n.ok?a(n.value):a(await r(n.error,n.cause))}function Ce(e){if(typeof e!="object"||e===null||!("ok"in e))return null;let r=e;return r.ok===!0&&"value"in r?a(r.value):r.ok===!1&&"error"in r?u(r.error,{cause:r.cause}):null}function ye(e){if(typeof e!="object"||e===null||!("ok"in e))return!1;let r=e;return r.ok===!0&&"value"in r||r.ok===!1&&"error"in r}function Re(e){let r=[];for(let n of e){if(!n.ok)return n;r.push(n.value)}return a(r)}async function ke(e){let r=[];for(let n of e)try{let t=await n;if(!t.ok)return t;r.push(t.value)}catch(t){return u({type:p,cause:t},{cause:{type:"PROMISE_REJECTION",reason:t}})}return a(r)}function me(e){let r=[],n=[];for(let t of e)t.ok?r.push(t.value):n.push({error:t.error,cause:t.cause});return n.length>0?u(n):a(r)}async function ge(e){let r=await Promise.all(e.map(o=>Promise.resolve(o).then(s=>({status:"result",result:s})).catch(s=>({status:"rejected",error:{type:p,cause:s},cause:{type:"PROMISE_REJECTION",reason:s}})))),n=[],t=[];for(let o of r)o.status==="rejected"?t.push({error:o.error,cause:o.cause}):o.result.ok?n.push(o.result.value):t.push({error:o.result.error,cause:o.result.cause});return t.length>0?u(t):a(n)}function xe(e){let r=[],n=[];for(let t of e)t.ok?r.push(t.value):n.push(t.error);return{values:r,errors:n}}function we(e){if(e.length===0)return u({type:"EMPTY_INPUT",message:"any() requires at least one Result"});let r;for(let n of e){if(n.ok)return n;r||(r=n)}return r}async function Ae(e){return e.length===0?u({type:"EMPTY_INPUT",message:"anyAsync() requires at least one Result"}):new Promise(r=>{let n=!1,t=e.length,o=null;for(let s of e)Promise.resolve(s).catch(i=>u({type:p,cause:i},{cause:{type:"PROMISE_REJECTION",reason:i}})).then(i=>{if(!n){if(i.ok){n=!0,r(i);return}o||(o=i),t--,t===0&&r(o)}})})}function v(e,r){return e.ok?r.ok?a([e.value,r.value]):r:e}async function he(e,r){let n=s=>Promise.resolve(s).catch(i=>u({type:p,cause:i},{cause:{type:"PROMISE_REJECTION",reason:i}})),[t,o]=await Promise.all([n(e),n(r)]);return v(t,o)}function Pe(e){return e.ok?e.value:e}var y="DESERIALIZATION_ERROR";function ve(e){if(typeof e!="object"||e===null)return u({type:y,value:e});if(!("ok"in e))return u({type:y,value:e});let r=e;return r.ok===!0&&"value"in r?a(r.value):r.ok===!1&&"error"in r?u(r.error,{cause:r.cause}):u({type:y,value:e})}function be(e){return e.ok?{ok:!0,value:e.value}:{ok:!1,error:e.error}}function Ue(e,r,n){if(m(e)){let o=r.UnexpectedError;return o?o(e):n(e)}let t=r[e];return t?t(e):n(e)}function b(e,...r){return r.reduce((n,t)=>t(n),e)}function U(...e){return r=>e.reduce((n,t)=>t(n),r)}function O(...e){return r=>e.reduceRight((n,t)=>t(n),r)}var B=e=>e;function Qe(e,r){return l(e)?a(r(e.value)):e}function er(e,r){return l(e)?r(e.value):e}function rr(e,r,n){return l(e)?a(r(e.value)):u(n(e.error),{cause:e.cause})}function nr(e,r){return f(e)?u(r(e.error),{cause:e.cause}):e}function tr(e,r){return l(e)&&r(e.value),e}function or(e,r){return f(e)&&r(e.error),e}function sr(e,r){return l(e)?r.ok(e.value):r.err(e.error,e.cause)}function ur(e,r){return l(e)?e.value:r(e.error)}function x(e,r){return l(e)?e:r(e.error)}function w(e,r){return l(e)?e.value:r}function A(e,r){return l(e)?e.value:r()}async function D(e,r){let n=await e;return l(n)?a(await r(n.value)):n}async function _(e,r){let n=await e;return l(n)?r(n.value):n}async function j(e,r){let n=await e;return l(n)&&await r(n.value),n}async function S(e,r){let n=await e;return f(n)&&await r(n.error),n}async function ar(e){if(e.length===0)return a([]);let r=new Array(e.length),n=0,t=!1;return new Promise(o=>{e.forEach((s,i)=>{s.then(E=>{t||(f(E)?(t=!0,o(E)):(r[i]=E.value,n++,n===e.length&&(t=!0,o(a(r)))))},E=>{t||(t=!0,o(u({type:p,cause:E},{cause:{type:"PROMISE_REJECTION",reason:E}})))})})})}async function F(e){return Promise.race(e.map(r=>r.catch(n=>u({type:p,cause:n},{cause:{type:"PROMISE_REJECTION",reason:n}}))))}function I(e,r){let n=[];for(let t=0;t<e.length;t++){let o=r(e[t],t);if(f(o))return o;n.push(o.value)}return a(n)}async function H(e,r){let n=[];for(let t=0;t<e.length;t++){let o=await r(e[t],t);if(f(o))return o;n.push(o.value)}return a(n)}async function K(e,r){return ar(e.map((n,t)=>r(n,t)))}var N={map:e=>r=>Qe(r,e),flatMap:e=>r=>er(r,e),bimap:(e,r)=>n=>rr(n,e,r),mapError:e=>r=>nr(r,e),tap:e=>r=>tr(r,e),tapError:e=>r=>or(r,e),match:e=>r=>sr(r,e),recover:e=>r=>ur(r,e),recoverWith:e=>r=>x(r,e),getOrElse:e=>r=>w(r,e),getOrElseLazy:e=>r=>A(r,e)};function Be(e,r){let n=t=>((...o)=>{let s=o.at(-1),i=o.length>0&&typeof s=="object"&&s!==null&&!Array.isArray(s)&&typeof s!="function",E=i?s:void 0,d=i?o.slice(0,-1):o,T={...r,...E?.deps??{}},M=E?{...E,deps:T}:{deps:T};return e[t](...d,M)});return{run:n("run"),runWithState:n("runWithState"),withDeps(t){return Be(e,{...r,...t})}}}var ir={...Oe,TaggedError:c,pipe:b,flow:U,compose:O,identity:B,R:N,recoverWith:x,getOrElse:w,getOrElseLazy:A,mapAsync:D,flatMapAsync:_,tapAsync:j,tapErrorAsync:S,race:F,traverse:I,traverseAsync:H,traverseParallel:K};0&&(module.exports={AWAITLY_CANCELLED,AWAITLY_TIMEOUT,AWAITLY_UNEXPECTED,Awaitly,DESERIALIZATION_ERROR,PROMISE_REJECTED,R,TaggedError,UnexpectedError,UnwrapError,all,allAsync,allSettled,allSettledAsync,andThen,any,anyAsync,bimap,compose,deserialize,err,flatMapAsync,flatten,flow,from,fromNullable,fromPromise,getOrElse,getOrElseLazy,hydrate,identity,isErr,isOk,isPromiseRejectedError,isSerializedResult,isUnexpectedError,map,mapAsync,mapError,mapErrorTry,mapTry,match,matchError,matchErrorPartial,ok,orElse,orElseAsync,partition,pipe,race,recover,recoverAsync,recoverWith,runOrNull,runOrThrow,runOrThrowAsync,runOrUndefined,serialize,tags,tap,tapAsync,tapError,tapErrorAsync,traverse,traverseAsync,traverseParallel,tryAsync,unwrap,unwrapOr,unwrapOrElse,withDeps,zip,zipAsync});
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all2) => {
|
|
7
|
+
for (var name in all2)
|
|
8
|
+
__defProp(target, name, { get: all2[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from2, except, desc) => {
|
|
11
|
+
if (from2 && typeof from2 === "object" || typeof from2 === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from2))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
ALL_SLUGS: () => ALL_SLUGS,
|
|
24
|
+
AWAITLY_CANCELLED: () => AWAITLY_CANCELLED,
|
|
25
|
+
AWAITLY_SLUGS: () => AWAITLY_SLUGS,
|
|
26
|
+
AWAITLY_SYSTEM_ERROR_CLASSES: () => AWAITLY_SYSTEM_ERROR_CLASSES,
|
|
27
|
+
AWAITLY_TIMEOUT: () => AWAITLY_TIMEOUT,
|
|
28
|
+
AWAITLY_UNEXPECTED: () => AWAITLY_UNEXPECTED,
|
|
29
|
+
CircuitBreakerOpenError: () => CircuitBreakerOpenError,
|
|
30
|
+
CircuitOpenError: () => CircuitOpenError,
|
|
31
|
+
CompensationError: () => CompensationError,
|
|
32
|
+
DESERIALIZATION_ERROR: () => DESERIALIZATION_ERROR,
|
|
33
|
+
Duration: () => Duration,
|
|
34
|
+
EARLY_EXIT_SYMBOL: () => EARLY_EXIT_SYMBOL,
|
|
35
|
+
Match: () => Match,
|
|
36
|
+
NetworkError: () => NetworkError,
|
|
37
|
+
NotFoundError: () => NotFoundError,
|
|
38
|
+
PROMISE_REJECTED: () => PROMISE_REJECTED,
|
|
39
|
+
RateLimitError: () => RateLimitError,
|
|
40
|
+
RetryExhaustedError: () => RetryExhaustedError,
|
|
41
|
+
STEP_TIMEOUT_MARKER: () => STEP_TIMEOUT_MARKER,
|
|
42
|
+
TaggedError: () => TaggedError,
|
|
43
|
+
TimeoutError: () => TimeoutError,
|
|
44
|
+
UnauthorizedError: () => UnauthorizedError,
|
|
45
|
+
UnexpectedError: () => UnexpectedError,
|
|
46
|
+
UnwrapError: () => UnwrapError,
|
|
47
|
+
ValidationError: () => ValidationError,
|
|
48
|
+
add: () => add,
|
|
49
|
+
all: () => all,
|
|
50
|
+
allAsync: () => allAsync,
|
|
51
|
+
allSettled: () => allSettled,
|
|
52
|
+
allSettledAsync: () => allSettledAsync,
|
|
53
|
+
andThen: () => andThen,
|
|
54
|
+
any: () => any,
|
|
55
|
+
anyAsync: () => anyAsync,
|
|
56
|
+
bimap: () => bimap,
|
|
57
|
+
cached: () => cached,
|
|
58
|
+
cachedFunction: () => cachedFunction,
|
|
59
|
+
cachedWithTTL: () => cachedWithTTL,
|
|
60
|
+
circuitBreakerPresets: () => circuitBreakerPresets,
|
|
61
|
+
clamp: () => clamp,
|
|
62
|
+
conditionalPolicy: () => conditionalPolicy,
|
|
63
|
+
createCache: () => createCache,
|
|
64
|
+
createCircuitBreaker: () => createCircuitBreaker,
|
|
65
|
+
createCombinedLimiter: () => createCombinedLimiter,
|
|
66
|
+
createConcurrencyLimiter: () => createConcurrencyLimiter,
|
|
67
|
+
createConditionalHelpers: () => createConditionalHelpers,
|
|
68
|
+
createCostBasedRateLimiter: () => createCostBasedRateLimiter,
|
|
69
|
+
createEarlyExit: () => createEarlyExit,
|
|
70
|
+
createFixedWindowLimiter: () => createFixedWindowLimiter,
|
|
71
|
+
createPolicyApplier: () => createPolicyApplier,
|
|
72
|
+
createPolicyBundle: () => createPolicyBundle,
|
|
73
|
+
createPolicyRegistry: () => createPolicyRegistry,
|
|
74
|
+
createRateLimiter: () => createRateLimiter,
|
|
75
|
+
createSingleflightGroup: () => createSingleflightGroup,
|
|
76
|
+
days: () => days,
|
|
77
|
+
deserialize: () => deserialize,
|
|
78
|
+
divide: () => divide,
|
|
79
|
+
envPolicy: () => envPolicy,
|
|
80
|
+
equals: () => equals,
|
|
81
|
+
err: () => err,
|
|
82
|
+
exhaustive: () => exhaustive,
|
|
83
|
+
fallback: () => fallback,
|
|
84
|
+
flatten: () => flatten,
|
|
85
|
+
format: () => format,
|
|
86
|
+
from: () => from,
|
|
87
|
+
fromNullable: () => fromNullable,
|
|
88
|
+
fromPromise: () => fromPromise,
|
|
89
|
+
getStepTimeoutMeta: () => getStepTimeoutMeta,
|
|
90
|
+
greaterThan: () => greaterThan,
|
|
91
|
+
greaterThanOrEqual: () => greaterThanOrEqual,
|
|
92
|
+
hours: () => hours,
|
|
93
|
+
hydrate: () => hydrate,
|
|
94
|
+
infinity: () => infinity,
|
|
95
|
+
isAwaitlyError: () => isAwaitlyError,
|
|
96
|
+
isAwaitlySlug: () => isAwaitlySlug,
|
|
97
|
+
isCircuitBreakerOpenError: () => isCircuitBreakerOpenError,
|
|
98
|
+
isCircuitOpenError: () => isCircuitOpenError,
|
|
99
|
+
isCompensationError: () => isCompensationError,
|
|
100
|
+
isDuration: () => isDuration,
|
|
101
|
+
isEarlyExit: () => isEarlyExit,
|
|
102
|
+
isErr: () => isErr,
|
|
103
|
+
isFinite: () => isFinite,
|
|
104
|
+
isInfinite: () => isInfinite,
|
|
105
|
+
isNetworkError: () => isNetworkError,
|
|
106
|
+
isNotFoundError: () => isNotFoundError,
|
|
107
|
+
isOk: () => isOk,
|
|
108
|
+
isOneOf: () => isOneOf,
|
|
109
|
+
isPromiseRejectedError: () => isPromiseRejectedError,
|
|
110
|
+
isQueueFullError: () => isQueueFullError,
|
|
111
|
+
isRateLimitError: () => isRateLimitError,
|
|
112
|
+
isRateLimitExceededError: () => isRateLimitExceededError,
|
|
113
|
+
isRetryExhaustedError: () => isRetryExhaustedError,
|
|
114
|
+
isSerializedResult: () => isSerializedResult,
|
|
115
|
+
isStepTimeoutError: () => isStepTimeoutError,
|
|
116
|
+
isTag: () => is,
|
|
117
|
+
isTimeoutError: () => isTimeoutError,
|
|
118
|
+
isUnauthorizedError: () => isUnauthorizedError,
|
|
119
|
+
isUnexpectedError: () => isUnexpectedError,
|
|
120
|
+
isValidationError: () => isValidationError,
|
|
121
|
+
isZero: () => isZero,
|
|
122
|
+
lessThan: () => lessThan,
|
|
123
|
+
lessThanOrEqual: () => lessThanOrEqual,
|
|
124
|
+
makeError: () => makeError,
|
|
125
|
+
map: () => map,
|
|
126
|
+
mapError: () => mapError,
|
|
127
|
+
mapErrorTry: () => mapErrorTry,
|
|
128
|
+
mapTry: () => mapTry,
|
|
129
|
+
match: () => match,
|
|
130
|
+
matchError: () => matchError,
|
|
131
|
+
matchErrorPartial: () => matchErrorPartial,
|
|
132
|
+
matchOrElse: () => orElse2,
|
|
133
|
+
matchTag: () => tag,
|
|
134
|
+
matchTags: () => tags2,
|
|
135
|
+
matchValue: () => matchValue,
|
|
136
|
+
max: () => max,
|
|
137
|
+
mergePolicies: () => mergePolicies,
|
|
138
|
+
millis: () => millis,
|
|
139
|
+
min: () => min,
|
|
140
|
+
minutes: () => minutes,
|
|
141
|
+
multiply: () => multiply,
|
|
142
|
+
ok: () => ok,
|
|
143
|
+
once: () => once,
|
|
144
|
+
orElse: () => orElse,
|
|
145
|
+
orElseAsync: () => orElseAsync,
|
|
146
|
+
orElseValue: () => orElseValue,
|
|
147
|
+
parse: () => parse,
|
|
148
|
+
partition: () => partition,
|
|
149
|
+
rateLimiterPresets: () => rateLimiterPresets,
|
|
150
|
+
recover: () => recover,
|
|
151
|
+
recoverAsync: () => recoverAsync,
|
|
152
|
+
retry: () => retry,
|
|
153
|
+
retryPolicies: () => retryPolicies,
|
|
154
|
+
retryPolicy: () => retryPolicy,
|
|
155
|
+
run: () => run,
|
|
156
|
+
runOrNull: () => runOrNull,
|
|
157
|
+
runOrThrow: () => runOrThrow,
|
|
158
|
+
runOrThrowAsync: () => runOrThrowAsync,
|
|
159
|
+
runOrUndefined: () => runOrUndefined,
|
|
160
|
+
seconds: () => seconds,
|
|
161
|
+
serialize: () => serialize,
|
|
162
|
+
servicePolicies: () => servicePolicies,
|
|
163
|
+
singleflight: () => singleflight,
|
|
164
|
+
slugCategory: () => slugCategory,
|
|
165
|
+
slugDocsUrl: () => slugDocsUrl,
|
|
166
|
+
stepOptions: () => stepOptions,
|
|
167
|
+
subtract: () => subtract,
|
|
168
|
+
tags: () => tags,
|
|
169
|
+
tap: () => tap,
|
|
170
|
+
tapError: () => tapError,
|
|
171
|
+
timeout: () => timeout,
|
|
172
|
+
timeoutPolicies: () => timeoutPolicies,
|
|
173
|
+
timeoutPolicy: () => timeoutPolicy,
|
|
174
|
+
toDays: () => toDays,
|
|
175
|
+
toHours: () => toHours,
|
|
176
|
+
toMillis: () => toMillis,
|
|
177
|
+
toMinutes: () => toMinutes,
|
|
178
|
+
toSeconds: () => toSeconds,
|
|
179
|
+
tryAsync: () => tryAsync,
|
|
180
|
+
unless: () => unless,
|
|
181
|
+
unlessOr: () => unlessOr,
|
|
182
|
+
unwrap: () => unwrap,
|
|
183
|
+
unwrapOr: () => unwrapOr,
|
|
184
|
+
unwrapOrElse: () => unwrapOrElse,
|
|
185
|
+
when: () => when2,
|
|
186
|
+
whenOr: () => whenOr,
|
|
187
|
+
withDeps: () => withDeps,
|
|
188
|
+
withPolicies: () => withPolicies,
|
|
189
|
+
withPolicy: () => withPolicy,
|
|
190
|
+
zero: () => zero,
|
|
191
|
+
zip: () => zip,
|
|
192
|
+
zipAsync: () => zipAsync
|
|
193
|
+
});
|
|
194
|
+
module.exports = __toCommonJS(src_exports);
|
|
195
|
+
|
|
196
|
+
// src/slugs.ts
|
|
197
|
+
var AWAITLY_SLUGS = {
|
|
198
|
+
// --- step-* ---
|
|
199
|
+
"step-require-id": "step-require-id",
|
|
200
|
+
"step-no-immediate-execution": "step-no-immediate-execution",
|
|
201
|
+
"step-require-thunk-for-key": "step-require-thunk-for-key",
|
|
202
|
+
"step-no-bare-await": "step-no-bare-await",
|
|
203
|
+
"step-no-try-catch-wrap": "step-no-try-catch-wrap",
|
|
204
|
+
"step-stable-cache-keys": "step-stable-cache-keys",
|
|
205
|
+
// --- workflow-* ---
|
|
206
|
+
"workflow-no-floating": "workflow-no-floating",
|
|
207
|
+
"workflow-options-position": "workflow-options-position",
|
|
208
|
+
"workflow-callback-shape": "workflow-callback-shape",
|
|
209
|
+
"workflow-no-callable-form": "workflow-no-callable-form",
|
|
210
|
+
"workflow-no-dynamic-import": "workflow-no-dynamic-import",
|
|
211
|
+
"workflow-prefer-step-if": "workflow-prefer-step-if",
|
|
212
|
+
"workflow-prefer-step-foreach": "workflow-prefer-step-foreach",
|
|
213
|
+
// --- result-* ---
|
|
214
|
+
"result-no-floating": "result-no-floating",
|
|
215
|
+
"result-require-handling": "result-require-handling",
|
|
216
|
+
"result-no-double-wrap": "result-no-double-wrap",
|
|
217
|
+
"result-no-manual-propagation": "result-no-manual-propagation",
|
|
218
|
+
"result-no-direct-ok-err": "result-no-direct-ok-err",
|
|
219
|
+
// --- error-* ---
|
|
220
|
+
"error-check-unexpected-first": "error-check-unexpected-first",
|
|
221
|
+
"error-access-cause": "error-access-cause",
|
|
222
|
+
"error-normalize": "error-normalize",
|
|
223
|
+
"error-no-throw-in-deps": "error-no-throw-in-deps",
|
|
224
|
+
// --- concurrency-* ---
|
|
225
|
+
"concurrency-no-promise-all": "concurrency-no-promise-all",
|
|
226
|
+
"concurrency-no-promise-race": "concurrency-no-promise-race",
|
|
227
|
+
"concurrency-no-promise-allsettled": "concurrency-no-promise-allsettled",
|
|
228
|
+
// --- runtime-* ---
|
|
229
|
+
"runtime-step-timeout": "runtime-step-timeout",
|
|
230
|
+
"runtime-step-aborted": "runtime-step-aborted",
|
|
231
|
+
"runtime-retry-exhausted": "runtime-retry-exhausted",
|
|
232
|
+
"runtime-rate-limit": "runtime-rate-limit",
|
|
233
|
+
"runtime-circuit-open": "runtime-circuit-open",
|
|
234
|
+
"runtime-unexpected": "runtime-unexpected",
|
|
235
|
+
"runtime-resolver-not-found": "runtime-resolver-not-found",
|
|
236
|
+
"runtime-saga-compensation": "runtime-saga-compensation"
|
|
237
|
+
};
|
|
238
|
+
function slugCategory(slug) {
|
|
239
|
+
return slug.split("-")[0];
|
|
240
|
+
}
|
|
241
|
+
function slugDocsUrl(slug) {
|
|
242
|
+
return `https://jagreehal.github.io/awaitly/rules/#${slug}`;
|
|
243
|
+
}
|
|
244
|
+
function isAwaitlySlug(value) {
|
|
245
|
+
return Object.prototype.hasOwnProperty.call(AWAITLY_SLUGS, value);
|
|
246
|
+
}
|
|
247
|
+
var ALL_SLUGS = Object.keys(
|
|
248
|
+
AWAITLY_SLUGS
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
// src/tagged-error.ts
|
|
252
|
+
var InternalTaggedErrorBase = class extends Error {
|
|
253
|
+
type;
|
|
254
|
+
/** @deprecated Use `type`. */
|
|
255
|
+
_tag;
|
|
256
|
+
};
|
|
257
|
+
function TaggedError(tag2, options) {
|
|
258
|
+
return class extends InternalTaggedErrorBase {
|
|
259
|
+
type = tag2;
|
|
260
|
+
/** @deprecated Use `type`. */
|
|
261
|
+
_tag = tag2;
|
|
262
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
263
|
+
constructor(props, errorOptions) {
|
|
264
|
+
const message = options?.message ? options.message(props ?? {}) : tag2;
|
|
265
|
+
super(message);
|
|
266
|
+
this.name = tag2;
|
|
267
|
+
if (options?.slug !== void 0) {
|
|
268
|
+
if (!options.hint) {
|
|
269
|
+
throw new TypeError(
|
|
270
|
+
`TaggedError: 'hint' is required when 'slug' is set (slug: "${options.slug}")`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
Object.defineProperty(this, "code", {
|
|
274
|
+
value: options.slug,
|
|
275
|
+
enumerable: true,
|
|
276
|
+
writable: false,
|
|
277
|
+
configurable: false
|
|
278
|
+
});
|
|
279
|
+
Object.defineProperty(this, "hint", {
|
|
280
|
+
value: options.hint,
|
|
281
|
+
enumerable: true,
|
|
282
|
+
writable: false,
|
|
283
|
+
configurable: false
|
|
284
|
+
});
|
|
285
|
+
Object.defineProperty(this, "docsUrl", {
|
|
286
|
+
value: slugDocsUrl(options.slug),
|
|
287
|
+
enumerable: true,
|
|
288
|
+
writable: false,
|
|
289
|
+
configurable: false
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
293
|
+
if (props && typeof props === "object") {
|
|
294
|
+
let safeProps;
|
|
295
|
+
if (options?.slug !== void 0) {
|
|
296
|
+
const {
|
|
297
|
+
_tag: _,
|
|
298
|
+
type: _t,
|
|
299
|
+
name: _n,
|
|
300
|
+
message: _m,
|
|
301
|
+
stack: _s,
|
|
302
|
+
code: _c,
|
|
303
|
+
hint: _h,
|
|
304
|
+
docsUrl: _d,
|
|
305
|
+
...rest
|
|
306
|
+
} = props;
|
|
307
|
+
safeProps = rest;
|
|
308
|
+
} else {
|
|
309
|
+
const {
|
|
310
|
+
_tag: _,
|
|
311
|
+
type: _t,
|
|
312
|
+
name: _n,
|
|
313
|
+
message: _m,
|
|
314
|
+
stack: _s,
|
|
315
|
+
...rest
|
|
316
|
+
} = props;
|
|
317
|
+
safeProps = rest;
|
|
318
|
+
}
|
|
319
|
+
const hasUserCause = Object.prototype.hasOwnProperty.call(
|
|
320
|
+
safeProps,
|
|
321
|
+
"cause"
|
|
322
|
+
);
|
|
323
|
+
const userCause = hasUserCause ? safeProps.cause : void 0;
|
|
324
|
+
if (hasUserCause) {
|
|
325
|
+
delete safeProps.cause;
|
|
326
|
+
}
|
|
327
|
+
const hasOptionsCause = errorOptions?.cause !== void 0;
|
|
328
|
+
if (hasUserCause && hasOptionsCause) {
|
|
329
|
+
throw new TypeError(
|
|
330
|
+
"TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause"
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
Object.assign(this, safeProps);
|
|
334
|
+
if (hasUserCause) {
|
|
335
|
+
this.cause = userCause;
|
|
336
|
+
}
|
|
337
|
+
if (hasOptionsCause) {
|
|
338
|
+
this.cause = errorOptions?.cause;
|
|
339
|
+
}
|
|
340
|
+
} else if (errorOptions?.cause !== void 0) {
|
|
341
|
+
this.cause = errorOptions.cause;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
Object.defineProperty(TaggedError, Symbol.hasInstance, {
|
|
347
|
+
value: (instance) => instance instanceof InternalTaggedErrorBase
|
|
348
|
+
});
|
|
349
|
+
((TaggedError2) => {
|
|
350
|
+
function isError(value) {
|
|
351
|
+
return value instanceof Error;
|
|
352
|
+
}
|
|
353
|
+
TaggedError2.isError = isError;
|
|
354
|
+
function isTaggedError(value) {
|
|
355
|
+
return value instanceof InternalTaggedErrorBase;
|
|
356
|
+
}
|
|
357
|
+
TaggedError2.isTaggedError = isTaggedError;
|
|
358
|
+
function match2(error, handlers) {
|
|
359
|
+
const tag2 = error._tag;
|
|
360
|
+
const handler = handlers[tag2];
|
|
361
|
+
return handler(
|
|
362
|
+
error
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
TaggedError2.match = match2;
|
|
366
|
+
function matchPartial(error, handlers, otherwise) {
|
|
367
|
+
const tag2 = error._tag;
|
|
368
|
+
const handler = handlers[tag2];
|
|
369
|
+
if (handler) {
|
|
370
|
+
return handler(
|
|
371
|
+
error
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
return otherwise(error);
|
|
375
|
+
}
|
|
376
|
+
TaggedError2.matchPartial = matchPartial;
|
|
377
|
+
})(TaggedError || (TaggedError = {}));
|
|
378
|
+
|
|
379
|
+
// src/errors.ts
|
|
380
|
+
function makeError(tag2, options) {
|
|
381
|
+
const messageGenerator = options?.message ?? (() => tag2);
|
|
382
|
+
const defaults = options?.defaults ?? {};
|
|
383
|
+
const BaseClass = TaggedError(tag2, {
|
|
384
|
+
message: (props) => messageGenerator({ ...defaults, ...props })
|
|
385
|
+
});
|
|
386
|
+
return class extends BaseClass {
|
|
387
|
+
constructor(props) {
|
|
388
|
+
super({ ...defaults, ...props });
|
|
389
|
+
Object.assign(this, { ...defaults, ...props });
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
var TimeoutError = class extends (/* @__PURE__ */ TaggedError("TimeoutError", {
|
|
394
|
+
slug: "runtime-step-timeout",
|
|
395
|
+
hint: "Increase the step's timeout option, or check why the upstream operation is slow.",
|
|
396
|
+
message: (p) => p.operation ? `TimeoutError: ${p.operation} timed out after ${p.ms}ms` : `TimeoutError: Operation timed out after ${p.ms}ms`
|
|
397
|
+
})) {
|
|
398
|
+
};
|
|
399
|
+
var RetryExhaustedError = class extends (/* @__PURE__ */ TaggedError("RetryExhaustedError", {
|
|
400
|
+
slug: "runtime-retry-exhausted",
|
|
401
|
+
hint: "All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",
|
|
402
|
+
message: (p) => p.operation ? `RetryExhaustedError: ${p.operation} failed after ${p.attempts} attempts` : `RetryExhaustedError: Operation failed after ${p.attempts} attempts`
|
|
403
|
+
})) {
|
|
404
|
+
};
|
|
405
|
+
var RateLimitError = class extends (/* @__PURE__ */ TaggedError("RateLimitError", {
|
|
406
|
+
slug: "runtime-rate-limit",
|
|
407
|
+
hint: "Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",
|
|
408
|
+
message: (p) => p.limiterName ? `RateLimitError: Rate limit exceeded for ${p.limiterName}${p.retryAfterMs ? `, retry after ${p.retryAfterMs}ms` : ""}` : `RateLimitError: Rate limit exceeded${p.retryAfterMs ? `, retry after ${p.retryAfterMs}ms` : ""}`
|
|
409
|
+
})) {
|
|
410
|
+
};
|
|
411
|
+
var CircuitBreakerOpenError = class extends (/* @__PURE__ */ TaggedError(
|
|
412
|
+
"CircuitBreakerOpenError",
|
|
413
|
+
{
|
|
414
|
+
slug: "runtime-circuit-open",
|
|
415
|
+
hint: "The circuit is open. Wait for it to half-open or fall back to a degraded path.",
|
|
416
|
+
message: (p) => `CircuitBreakerOpenError: Circuit ${p.circuitName} is ${p.state ?? "OPEN"}${p.retryAfterMs ? `, retry after ${Math.ceil(p.retryAfterMs / 1e3)}s` : ""}`
|
|
417
|
+
}
|
|
418
|
+
)) {
|
|
419
|
+
};
|
|
420
|
+
var ValidationError = class extends (/* @__PURE__ */ TaggedError("ValidationError", {
|
|
421
|
+
message: (p) => `ValidationError: Invalid ${p.field} - ${p.reason}`
|
|
422
|
+
})) {
|
|
423
|
+
};
|
|
424
|
+
var NotFoundError = class extends (/* @__PURE__ */ TaggedError("NotFoundError", {
|
|
425
|
+
message: (p) => p.id ? `NotFoundError: ${p.resource} with id ${p.id} not found` : `NotFoundError: ${p.resource} not found`
|
|
426
|
+
})) {
|
|
427
|
+
};
|
|
428
|
+
var UnauthorizedError = class extends (/* @__PURE__ */ TaggedError("UnauthorizedError", {
|
|
429
|
+
message: (p) => p.reason ? `UnauthorizedError: ${p.reason}` : p.action && p.resource ? `UnauthorizedError: Not authorized to ${p.action} ${p.resource}` : "UnauthorizedError: Access denied"
|
|
430
|
+
})) {
|
|
431
|
+
};
|
|
432
|
+
var NetworkError = class extends (/* @__PURE__ */ TaggedError("NetworkError", {
|
|
433
|
+
message: (p) => p.url ? `NetworkError: ${p.reason} (${p.url})` : `NetworkError: ${p.reason}`
|
|
434
|
+
})) {
|
|
435
|
+
};
|
|
436
|
+
var CompensationError = class extends (/* @__PURE__ */ TaggedError("CompensationError", {
|
|
437
|
+
slug: "runtime-saga-compensation",
|
|
438
|
+
hint: "A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",
|
|
439
|
+
message: (p) => `CompensationError: Failed to compensate step ${p.step}`
|
|
440
|
+
})) {
|
|
441
|
+
};
|
|
442
|
+
var UnexpectedError = class extends (/* @__PURE__ */ TaggedError("UnexpectedError", {
|
|
443
|
+
slug: "runtime-unexpected",
|
|
444
|
+
hint: "An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",
|
|
445
|
+
message: (p) => `UnexpectedError: ${p.cause instanceof Error ? p.cause.message : String(p.cause ?? "unknown")}`
|
|
446
|
+
})) {
|
|
447
|
+
};
|
|
448
|
+
var AWAITLY_SYSTEM_ERROR_CLASSES = [
|
|
449
|
+
TimeoutError,
|
|
450
|
+
RetryExhaustedError,
|
|
451
|
+
RateLimitError,
|
|
452
|
+
CircuitBreakerOpenError,
|
|
453
|
+
CompensationError,
|
|
454
|
+
UnexpectedError
|
|
455
|
+
];
|
|
456
|
+
function isTimeoutError(error) {
|
|
457
|
+
return TaggedError.isTaggedError(error) && error._tag === "TimeoutError";
|
|
458
|
+
}
|
|
459
|
+
function isRetryExhaustedError(error) {
|
|
460
|
+
return TaggedError.isTaggedError(error) && error._tag === "RetryExhaustedError";
|
|
461
|
+
}
|
|
462
|
+
function isRateLimitError(error) {
|
|
463
|
+
return TaggedError.isTaggedError(error) && error._tag === "RateLimitError";
|
|
464
|
+
}
|
|
465
|
+
function isCircuitBreakerOpenError(error) {
|
|
466
|
+
return TaggedError.isTaggedError(error) && error._tag === "CircuitBreakerOpenError";
|
|
467
|
+
}
|
|
468
|
+
function isValidationError(error) {
|
|
469
|
+
return TaggedError.isTaggedError(error) && error._tag === "ValidationError";
|
|
470
|
+
}
|
|
471
|
+
function isNotFoundError(error) {
|
|
472
|
+
return TaggedError.isTaggedError(error) && error._tag === "NotFoundError";
|
|
473
|
+
}
|
|
474
|
+
function isUnauthorizedError(error) {
|
|
475
|
+
return TaggedError.isTaggedError(error) && error._tag === "UnauthorizedError";
|
|
476
|
+
}
|
|
477
|
+
function isNetworkError(error) {
|
|
478
|
+
return TaggedError.isTaggedError(error) && error._tag === "NetworkError";
|
|
479
|
+
}
|
|
480
|
+
function isCompensationError(error) {
|
|
481
|
+
return TaggedError.isTaggedError(error) && error._tag === "CompensationError";
|
|
482
|
+
}
|
|
483
|
+
function isAwaitlyError(error) {
|
|
484
|
+
if (!TaggedError.isTaggedError(error)) return false;
|
|
485
|
+
const tag2 = error._tag;
|
|
486
|
+
return [
|
|
487
|
+
"TimeoutError",
|
|
488
|
+
"RetryExhaustedError",
|
|
489
|
+
"RateLimitError",
|
|
490
|
+
"CircuitBreakerOpenError",
|
|
491
|
+
"ValidationError",
|
|
492
|
+
"NotFoundError",
|
|
493
|
+
"UnauthorizedError",
|
|
494
|
+
"NetworkError",
|
|
495
|
+
"CompensationError",
|
|
496
|
+
"UnexpectedError"
|
|
497
|
+
].includes(tag2);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// src/result/index.ts
|
|
501
|
+
var PROMISE_REJECTED = "PROMISE_REJECTED";
|
|
502
|
+
var AWAITLY_UNEXPECTED = "AWAITLY_UNEXPECTED";
|
|
503
|
+
var AWAITLY_CANCELLED = "AWAITLY_CANCELLED";
|
|
504
|
+
var AWAITLY_TIMEOUT = "AWAITLY_TIMEOUT";
|
|
505
|
+
var tags = (...t) => t;
|
|
506
|
+
function ok(value) {
|
|
507
|
+
return { ok: true, value };
|
|
508
|
+
}
|
|
509
|
+
function err(error, options) {
|
|
510
|
+
const cause = options?.cause;
|
|
511
|
+
return { ok: false, error, ...cause !== void 0 ? { cause } : {} };
|
|
512
|
+
}
|
|
513
|
+
var isOk = (r) => r.ok;
|
|
514
|
+
var isErr = (r) => !r.ok;
|
|
515
|
+
var isUnexpectedError = (e) => e instanceof UnexpectedError || typeof e === "object" && e !== null && "_tag" in e && e._tag === "UnexpectedError";
|
|
516
|
+
var isPromiseRejectedError = (e) => typeof e === "object" && e !== null && "type" in e && e.type === PROMISE_REJECTED;
|
|
517
|
+
function matchError(errorOrHandlers, handlers) {
|
|
518
|
+
if (handlers === void 0) {
|
|
519
|
+
const h = errorOrHandlers;
|
|
520
|
+
return (e) => matchError(e, h);
|
|
521
|
+
}
|
|
522
|
+
const error = errorOrHandlers;
|
|
523
|
+
if (isUnexpectedError(error)) {
|
|
524
|
+
return handlers.UnexpectedError(error);
|
|
525
|
+
}
|
|
526
|
+
return handlers[error](error);
|
|
527
|
+
}
|
|
528
|
+
var UnwrapError = class extends Error {
|
|
529
|
+
error;
|
|
530
|
+
cause;
|
|
531
|
+
constructor(result) {
|
|
532
|
+
const errorStr = typeof result.error === "string" ? result.error : JSON.stringify(result.error);
|
|
533
|
+
super(`Attempted to unwrap an Err: ${errorStr}`);
|
|
534
|
+
this.name = "UnwrapError";
|
|
535
|
+
this.error = result.error;
|
|
536
|
+
this.cause = result.cause;
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
var unwrap = (r) => {
|
|
540
|
+
if (r.ok) return r.value;
|
|
541
|
+
throw new UnwrapError(r);
|
|
542
|
+
};
|
|
543
|
+
var unwrapOr = (r, defaultValue) => r.ok ? r.value : defaultValue;
|
|
544
|
+
var unwrapOrElse = (r, fn) => r.ok ? r.value : fn(r.error, r.cause);
|
|
545
|
+
var runOrThrow = (r) => unwrap(r);
|
|
546
|
+
var runOrThrowAsync = (ar) => Promise.resolve(ar).then(unwrap);
|
|
547
|
+
var runOrNull = (r) => r.ok ? r.value : null;
|
|
548
|
+
var runOrUndefined = (r) => r.ok ? r.value : void 0;
|
|
549
|
+
function from(fn, onError) {
|
|
550
|
+
try {
|
|
551
|
+
return ok(fn());
|
|
552
|
+
} catch (cause) {
|
|
553
|
+
return onError ? err(onError(cause), { cause }) : err(cause);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
async function fromPromise(promise, onError) {
|
|
557
|
+
try {
|
|
558
|
+
return ok(await promise);
|
|
559
|
+
} catch (cause) {
|
|
560
|
+
return onError ? err(onError(cause), { cause }) : err(cause);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
async function tryAsync(fn, onError) {
|
|
564
|
+
try {
|
|
565
|
+
return ok(await fn());
|
|
566
|
+
} catch (cause) {
|
|
567
|
+
return onError ? err(onError(cause), { cause }) : err(cause);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
function fromNullable(value, onNull) {
|
|
571
|
+
return value != null ? ok(value) : err(onNull());
|
|
572
|
+
}
|
|
573
|
+
function map(r, fn) {
|
|
574
|
+
return r.ok ? ok(fn(r.value)) : r;
|
|
575
|
+
}
|
|
576
|
+
function mapError(r, fn) {
|
|
577
|
+
return r.ok ? r : err(fn(r.error, r.cause), { cause: r.cause });
|
|
578
|
+
}
|
|
579
|
+
function match(r, handlers) {
|
|
580
|
+
if (handlers === void 0) {
|
|
581
|
+
const h = r;
|
|
582
|
+
return (result) => match(result, h);
|
|
583
|
+
}
|
|
584
|
+
if (r.ok) return handlers.ok(r.value);
|
|
585
|
+
if (typeof handlers.err === "function") return handlers.err(r.error, r.cause);
|
|
586
|
+
const e = r.error;
|
|
587
|
+
const key = typeof e === "string" ? e : e?.type ?? e?._tag;
|
|
588
|
+
const handler = key === void 0 ? void 0 : handlers[key];
|
|
589
|
+
if (typeof handler === "function") return handler(e, r.cause);
|
|
590
|
+
throw new TypeError(
|
|
591
|
+
`match: no handler for error type "${String(key)}". Add a handler for it, or use the { ok, err } form for a catch-all.`
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
function andThen(r, fn) {
|
|
595
|
+
return r.ok ? fn(r.value) : r;
|
|
596
|
+
}
|
|
597
|
+
function tap(r, fn) {
|
|
598
|
+
if (r.ok) fn(r.value);
|
|
599
|
+
return r;
|
|
600
|
+
}
|
|
601
|
+
function tapError(r, fn) {
|
|
602
|
+
if (!r.ok) fn(r.error, r.cause);
|
|
603
|
+
return r;
|
|
604
|
+
}
|
|
605
|
+
function mapTry(r, fn, onError) {
|
|
606
|
+
if (!r.ok) return r;
|
|
607
|
+
try {
|
|
608
|
+
return ok(fn(r.value));
|
|
609
|
+
} catch (error) {
|
|
610
|
+
return err(onError(error), { cause: error });
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function mapErrorTry(r, fn, onError) {
|
|
614
|
+
if (r.ok) return r;
|
|
615
|
+
try {
|
|
616
|
+
return err(fn(r.error), { cause: r.cause });
|
|
617
|
+
} catch (error) {
|
|
618
|
+
return err(onError(error), { cause: error });
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function bimap(r, onOk, onErr) {
|
|
622
|
+
return r.ok ? ok(onOk(r.value)) : err(onErr(r.error, r.cause), { cause: r.cause });
|
|
623
|
+
}
|
|
624
|
+
function orElse(r, fn) {
|
|
625
|
+
return r.ok ? r : fn(r.error, r.cause);
|
|
626
|
+
}
|
|
627
|
+
async function orElseAsync(r, fn) {
|
|
628
|
+
return r.ok ? r : fn(r.error, r.cause);
|
|
629
|
+
}
|
|
630
|
+
function recover(r, fn) {
|
|
631
|
+
return r.ok ? ok(r.value) : ok(fn(r.error, r.cause));
|
|
632
|
+
}
|
|
633
|
+
async function recoverAsync(r, fn) {
|
|
634
|
+
const resolved = await r;
|
|
635
|
+
if (resolved.ok) return ok(resolved.value);
|
|
636
|
+
return ok(await fn(resolved.error, resolved.cause));
|
|
637
|
+
}
|
|
638
|
+
function hydrate(value) {
|
|
639
|
+
if (typeof value !== "object" || value === null) return null;
|
|
640
|
+
if (!("ok" in value)) return null;
|
|
641
|
+
const obj = value;
|
|
642
|
+
if (obj.ok === true && "value" in obj) {
|
|
643
|
+
return ok(obj.value);
|
|
644
|
+
}
|
|
645
|
+
if (obj.ok === false && "error" in obj) {
|
|
646
|
+
return err(obj.error, { cause: obj.cause });
|
|
647
|
+
}
|
|
648
|
+
return null;
|
|
649
|
+
}
|
|
650
|
+
function isSerializedResult(value) {
|
|
651
|
+
if (typeof value !== "object" || value === null) return false;
|
|
652
|
+
if (!("ok" in value)) return false;
|
|
653
|
+
const obj = value;
|
|
654
|
+
return obj.ok === true && "value" in obj || obj.ok === false && "error" in obj;
|
|
655
|
+
}
|
|
656
|
+
function all(results) {
|
|
657
|
+
const values = [];
|
|
658
|
+
for (const result of results) {
|
|
659
|
+
if (!result.ok) {
|
|
660
|
+
return result;
|
|
661
|
+
}
|
|
662
|
+
values.push(result.value);
|
|
663
|
+
}
|
|
664
|
+
return ok(values);
|
|
665
|
+
}
|
|
666
|
+
async function allAsync(results) {
|
|
667
|
+
const values = [];
|
|
668
|
+
for (const resultOrPromise of results) {
|
|
669
|
+
try {
|
|
670
|
+
const r = await resultOrPromise;
|
|
671
|
+
if (!r.ok) return r;
|
|
672
|
+
values.push(r.value);
|
|
673
|
+
} catch (reason) {
|
|
674
|
+
return err(
|
|
675
|
+
{ type: PROMISE_REJECTED, cause: reason },
|
|
676
|
+
{ cause: { type: "PROMISE_REJECTION", reason } }
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return ok(values);
|
|
681
|
+
}
|
|
682
|
+
function allSettled(results) {
|
|
683
|
+
const values = [];
|
|
684
|
+
const errors = [];
|
|
685
|
+
for (const result of results) {
|
|
686
|
+
if (result.ok) {
|
|
687
|
+
values.push(result.value);
|
|
688
|
+
} else {
|
|
689
|
+
errors.push({ error: result.error, cause: result.cause });
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
if (errors.length > 0) {
|
|
693
|
+
return err(errors);
|
|
694
|
+
}
|
|
695
|
+
return ok(values);
|
|
696
|
+
}
|
|
697
|
+
async function allSettledAsync(results) {
|
|
698
|
+
const settled = await Promise.all(
|
|
699
|
+
results.map(
|
|
700
|
+
(item) => Promise.resolve(item).then((result) => ({ status: "result", result })).catch((reason) => ({
|
|
701
|
+
status: "rejected",
|
|
702
|
+
error: { type: PROMISE_REJECTED, cause: reason },
|
|
703
|
+
cause: { type: "PROMISE_REJECTION", reason }
|
|
704
|
+
}))
|
|
705
|
+
)
|
|
706
|
+
);
|
|
707
|
+
const values = [];
|
|
708
|
+
const errors = [];
|
|
709
|
+
for (const item of settled) {
|
|
710
|
+
if (item.status === "rejected") {
|
|
711
|
+
errors.push({ error: item.error, cause: item.cause });
|
|
712
|
+
} else if (item.result.ok) {
|
|
713
|
+
values.push(item.result.value);
|
|
714
|
+
} else {
|
|
715
|
+
errors.push({ error: item.result.error, cause: item.result.cause });
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
if (errors.length > 0) {
|
|
719
|
+
return err(errors);
|
|
720
|
+
}
|
|
721
|
+
return ok(values);
|
|
722
|
+
}
|
|
723
|
+
function partition(results) {
|
|
724
|
+
const values = [];
|
|
725
|
+
const errors = [];
|
|
726
|
+
for (const r of results) {
|
|
727
|
+
if (r.ok) values.push(r.value);
|
|
728
|
+
else errors.push(r.error);
|
|
729
|
+
}
|
|
730
|
+
return { values, errors };
|
|
731
|
+
}
|
|
732
|
+
function any(results) {
|
|
733
|
+
if (results.length === 0) {
|
|
734
|
+
return err({ type: "EMPTY_INPUT", message: "any() requires at least one Result" });
|
|
735
|
+
}
|
|
736
|
+
let firstErr;
|
|
737
|
+
for (const r of results) {
|
|
738
|
+
if (r.ok) return r;
|
|
739
|
+
if (!firstErr) firstErr = r;
|
|
740
|
+
}
|
|
741
|
+
return firstErr;
|
|
742
|
+
}
|
|
743
|
+
async function anyAsync(results) {
|
|
744
|
+
if (results.length === 0) {
|
|
745
|
+
return err({ type: "EMPTY_INPUT", message: "anyAsync() requires at least one Result" });
|
|
746
|
+
}
|
|
747
|
+
return new Promise((resolve) => {
|
|
748
|
+
let settled = false;
|
|
749
|
+
let pendingCount = results.length;
|
|
750
|
+
let firstError = null;
|
|
751
|
+
for (const item of results) {
|
|
752
|
+
Promise.resolve(item).catch(
|
|
753
|
+
(reason) => err(
|
|
754
|
+
{ type: PROMISE_REJECTED, cause: reason },
|
|
755
|
+
{ cause: { type: "PROMISE_REJECTION", reason } }
|
|
756
|
+
)
|
|
757
|
+
).then((result) => {
|
|
758
|
+
if (settled) return;
|
|
759
|
+
if (result.ok) {
|
|
760
|
+
settled = true;
|
|
761
|
+
resolve(result);
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (!firstError) firstError = result;
|
|
765
|
+
pendingCount--;
|
|
766
|
+
if (pendingCount === 0) {
|
|
767
|
+
resolve(firstError);
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
function zip(a, b) {
|
|
774
|
+
if (!a.ok) return a;
|
|
775
|
+
if (!b.ok) return b;
|
|
776
|
+
return ok([a.value, b.value]);
|
|
777
|
+
}
|
|
778
|
+
async function zipAsync(a, b) {
|
|
779
|
+
const wrapRejection = (p) => Promise.resolve(p).catch(
|
|
780
|
+
(reason) => err(
|
|
781
|
+
{ type: PROMISE_REJECTED, cause: reason },
|
|
782
|
+
{ cause: { type: "PROMISE_REJECTION", reason } }
|
|
783
|
+
)
|
|
784
|
+
);
|
|
785
|
+
const [ra, rb] = await Promise.all([wrapRejection(a), wrapRejection(b)]);
|
|
786
|
+
return zip(ra, rb);
|
|
787
|
+
}
|
|
788
|
+
function flatten(result) {
|
|
789
|
+
if (!result.ok) return result;
|
|
790
|
+
return result.value;
|
|
791
|
+
}
|
|
792
|
+
var DESERIALIZATION_ERROR = "DESERIALIZATION_ERROR";
|
|
793
|
+
function deserialize(value) {
|
|
794
|
+
if (typeof value !== "object" || value === null) {
|
|
795
|
+
return err({ type: DESERIALIZATION_ERROR, value });
|
|
796
|
+
}
|
|
797
|
+
if (!("ok" in value)) {
|
|
798
|
+
return err({ type: DESERIALIZATION_ERROR, value });
|
|
799
|
+
}
|
|
800
|
+
const obj = value;
|
|
801
|
+
if (obj.ok === true && "value" in obj) {
|
|
802
|
+
return ok(obj.value);
|
|
803
|
+
}
|
|
804
|
+
if (obj.ok === false && "error" in obj) {
|
|
805
|
+
return err(obj.error, { cause: obj.cause });
|
|
806
|
+
}
|
|
807
|
+
return err({ type: DESERIALIZATION_ERROR, value });
|
|
808
|
+
}
|
|
809
|
+
function serialize(result) {
|
|
810
|
+
return result.ok ? { ok: true, value: result.value } : { ok: false, error: result.error };
|
|
811
|
+
}
|
|
812
|
+
function matchErrorPartial(error, handlers, fallback2) {
|
|
813
|
+
if (isUnexpectedError(error)) {
|
|
814
|
+
const h2 = handlers.UnexpectedError;
|
|
815
|
+
return h2 ? h2(error) : fallback2(error);
|
|
816
|
+
}
|
|
817
|
+
const h = handlers[error];
|
|
818
|
+
return h ? h(error) : fallback2(error);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// src/di.ts
|
|
822
|
+
function withDeps(workflow, overrides) {
|
|
823
|
+
const forward = (method) => ((...args) => {
|
|
824
|
+
const last = args.at(-1);
|
|
825
|
+
const hasConfig = args.length > 0 && typeof last === "object" && last !== null && !Array.isArray(last) && typeof last !== "function";
|
|
826
|
+
const config = hasConfig ? last : void 0;
|
|
827
|
+
const head = hasConfig ? args.slice(0, -1) : args;
|
|
828
|
+
const mergedDeps = { ...overrides, ...config?.deps ?? {} };
|
|
829
|
+
const mergedConfig = config ? { ...config, deps: mergedDeps } : { deps: mergedDeps };
|
|
830
|
+
return workflow[method](...head, mergedConfig);
|
|
831
|
+
});
|
|
832
|
+
return {
|
|
833
|
+
run: forward("run"),
|
|
834
|
+
runWithState: forward("runWithState"),
|
|
835
|
+
withDeps(nextOverrides) {
|
|
836
|
+
return withDeps(workflow, { ...overrides, ...nextOverrides });
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// src/duration.ts
|
|
842
|
+
function millis(ms) {
|
|
843
|
+
return { _tag: "Duration", millis: ms };
|
|
844
|
+
}
|
|
845
|
+
function seconds(s) {
|
|
846
|
+
return { _tag: "Duration", millis: s * 1e3 };
|
|
847
|
+
}
|
|
848
|
+
function minutes(m) {
|
|
849
|
+
return { _tag: "Duration", millis: m * 60 * 1e3 };
|
|
850
|
+
}
|
|
851
|
+
function hours(h) {
|
|
852
|
+
return { _tag: "Duration", millis: h * 60 * 60 * 1e3 };
|
|
853
|
+
}
|
|
854
|
+
function days(d) {
|
|
855
|
+
return { _tag: "Duration", millis: d * 24 * 60 * 60 * 1e3 };
|
|
856
|
+
}
|
|
857
|
+
var zero = { _tag: "Duration", millis: 0 };
|
|
858
|
+
var infinity = { _tag: "Duration", millis: Infinity };
|
|
859
|
+
function toMillis(duration) {
|
|
860
|
+
return duration.millis;
|
|
861
|
+
}
|
|
862
|
+
function toSeconds(duration) {
|
|
863
|
+
return duration.millis / 1e3;
|
|
864
|
+
}
|
|
865
|
+
function toMinutes(duration) {
|
|
866
|
+
return duration.millis / (60 * 1e3);
|
|
867
|
+
}
|
|
868
|
+
function toHours(duration) {
|
|
869
|
+
return duration.millis / (60 * 60 * 1e3);
|
|
870
|
+
}
|
|
871
|
+
function toDays(duration) {
|
|
872
|
+
return duration.millis / (24 * 60 * 60 * 1e3);
|
|
873
|
+
}
|
|
874
|
+
function add(a, b) {
|
|
875
|
+
return { _tag: "Duration", millis: a.millis + b.millis };
|
|
876
|
+
}
|
|
877
|
+
function subtract(a, b) {
|
|
878
|
+
return { _tag: "Duration", millis: Math.max(0, a.millis - b.millis) };
|
|
879
|
+
}
|
|
880
|
+
function multiply(duration, factor) {
|
|
881
|
+
return { _tag: "Duration", millis: duration.millis * factor };
|
|
882
|
+
}
|
|
883
|
+
function divide(duration, divisor) {
|
|
884
|
+
return { _tag: "Duration", millis: duration.millis / divisor };
|
|
885
|
+
}
|
|
886
|
+
function lessThan(a, b) {
|
|
887
|
+
return a.millis < b.millis;
|
|
888
|
+
}
|
|
889
|
+
function lessThanOrEqual(a, b) {
|
|
890
|
+
return a.millis <= b.millis;
|
|
891
|
+
}
|
|
892
|
+
function greaterThan(a, b) {
|
|
893
|
+
return a.millis > b.millis;
|
|
894
|
+
}
|
|
895
|
+
function greaterThanOrEqual(a, b) {
|
|
896
|
+
return a.millis >= b.millis;
|
|
897
|
+
}
|
|
898
|
+
function equals(a, b) {
|
|
899
|
+
return a.millis === b.millis;
|
|
900
|
+
}
|
|
901
|
+
function min(a, b) {
|
|
902
|
+
return a.millis <= b.millis ? a : b;
|
|
903
|
+
}
|
|
904
|
+
function max(a, b) {
|
|
905
|
+
return a.millis >= b.millis ? a : b;
|
|
906
|
+
}
|
|
907
|
+
function clamp(duration, minimum, maximum) {
|
|
908
|
+
return min(max(duration, minimum), maximum);
|
|
909
|
+
}
|
|
910
|
+
function isZero(duration) {
|
|
911
|
+
return duration.millis === 0;
|
|
912
|
+
}
|
|
913
|
+
function isInfinite(duration) {
|
|
914
|
+
return duration.millis === Infinity;
|
|
915
|
+
}
|
|
916
|
+
function isFinite(duration) {
|
|
917
|
+
return Number.isFinite(duration.millis) && duration.millis > 0;
|
|
918
|
+
}
|
|
919
|
+
function isDuration(value) {
|
|
920
|
+
return typeof value === "object" && value !== null && "_tag" in value && value._tag === "Duration" && "millis" in value && typeof value.millis === "number";
|
|
921
|
+
}
|
|
922
|
+
function format(duration) {
|
|
923
|
+
const ms = duration.millis;
|
|
924
|
+
if (ms === Infinity) return "\u221E";
|
|
925
|
+
if (ms === 0) return "0ms";
|
|
926
|
+
const days2 = Math.floor(ms / (24 * 60 * 60 * 1e3));
|
|
927
|
+
const hours2 = Math.floor(ms % (24 * 60 * 60 * 1e3) / (60 * 60 * 1e3));
|
|
928
|
+
const minutes2 = Math.floor(ms % (60 * 60 * 1e3) / (60 * 1e3));
|
|
929
|
+
const seconds2 = Math.floor(ms % (60 * 1e3) / 1e3);
|
|
930
|
+
const millis2 = ms % 1e3;
|
|
931
|
+
const parts = [];
|
|
932
|
+
if (days2 > 0) parts.push(`${days2}d`);
|
|
933
|
+
if (hours2 > 0) parts.push(`${hours2}h`);
|
|
934
|
+
if (minutes2 > 0) parts.push(`${minutes2}m`);
|
|
935
|
+
if (seconds2 > 0) parts.push(`${seconds2}s`);
|
|
936
|
+
if (millis2 > 0 && parts.length === 0) parts.push(`${millis2}ms`);
|
|
937
|
+
return parts.join(" ") || "0ms";
|
|
938
|
+
}
|
|
939
|
+
function parse(input) {
|
|
940
|
+
const match2 = input.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);
|
|
941
|
+
if (!match2) return void 0;
|
|
942
|
+
const value = parseFloat(match2[1]);
|
|
943
|
+
const unit = match2[2].toLowerCase();
|
|
944
|
+
switch (unit) {
|
|
945
|
+
case "ms":
|
|
946
|
+
return millis(value);
|
|
947
|
+
case "s":
|
|
948
|
+
return seconds(value);
|
|
949
|
+
case "m":
|
|
950
|
+
return minutes(value);
|
|
951
|
+
case "h":
|
|
952
|
+
return hours(value);
|
|
953
|
+
case "d":
|
|
954
|
+
return days(value);
|
|
955
|
+
default:
|
|
956
|
+
return void 0;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
var Duration = {
|
|
960
|
+
// Constructors
|
|
961
|
+
millis,
|
|
962
|
+
seconds,
|
|
963
|
+
minutes,
|
|
964
|
+
hours,
|
|
965
|
+
days,
|
|
966
|
+
zero,
|
|
967
|
+
infinity,
|
|
968
|
+
// Conversions
|
|
969
|
+
toMillis,
|
|
970
|
+
toSeconds,
|
|
971
|
+
toMinutes,
|
|
972
|
+
toHours,
|
|
973
|
+
toDays,
|
|
974
|
+
// Operations
|
|
975
|
+
add,
|
|
976
|
+
subtract,
|
|
977
|
+
multiply,
|
|
978
|
+
divide,
|
|
979
|
+
// Comparisons
|
|
980
|
+
lessThan,
|
|
981
|
+
lessThanOrEqual,
|
|
982
|
+
greaterThan,
|
|
983
|
+
greaterThanOrEqual,
|
|
984
|
+
equals,
|
|
985
|
+
min,
|
|
986
|
+
max,
|
|
987
|
+
clamp,
|
|
988
|
+
// Predicates
|
|
989
|
+
isZero,
|
|
990
|
+
isInfinite,
|
|
991
|
+
isFinite,
|
|
992
|
+
isDuration,
|
|
993
|
+
// Formatting
|
|
994
|
+
format,
|
|
995
|
+
parse
|
|
996
|
+
};
|
|
997
|
+
|
|
998
|
+
// src/core/bound-steps.ts
|
|
999
|
+
var isDepResultShaped = (value) => typeof value === "object" && value !== null && "ok" in value && typeof value.ok === "boolean" && (value.ok ? "value" in value : "error" in value);
|
|
1000
|
+
var bindSteps = (deps, step) => {
|
|
1001
|
+
const steps = {};
|
|
1002
|
+
const invocationCounts = /* @__PURE__ */ new Map();
|
|
1003
|
+
for (const key of Object.keys(deps)) {
|
|
1004
|
+
const dep = deps[key];
|
|
1005
|
+
if (typeof dep !== "function") continue;
|
|
1006
|
+
steps[key] = (...args) => {
|
|
1007
|
+
const count = (invocationCounts.get(key) ?? 0) + 1;
|
|
1008
|
+
invocationCounts.set(key, count);
|
|
1009
|
+
const stepKey = count === 1 ? key : `${key}#${count}`;
|
|
1010
|
+
return step(stepKey, async () => {
|
|
1011
|
+
const value = await dep(...args);
|
|
1012
|
+
return isDepResultShaped(value) ? value : ok(value);
|
|
1013
|
+
});
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
return steps;
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
// src/core/policies.ts
|
|
1020
|
+
var toMs = (d) => typeof d === "number" ? d : toMillis(d);
|
|
1021
|
+
var attemptCall = async (fn, args) => {
|
|
1022
|
+
try {
|
|
1023
|
+
const value = await fn(...args);
|
|
1024
|
+
if (isDepResultShaped(value)) {
|
|
1025
|
+
return value.ok ? { kind: "ok", value: value.value } : { kind: "err", error: value.error, result: value };
|
|
1026
|
+
}
|
|
1027
|
+
return { kind: "ok", value };
|
|
1028
|
+
} catch (thrown) {
|
|
1029
|
+
return { kind: "threw", thrown };
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
var named = (wrapped, source) => {
|
|
1033
|
+
const name = source.name;
|
|
1034
|
+
if (name) {
|
|
1035
|
+
Object.defineProperty(wrapped, "name", { value: name, configurable: true });
|
|
1036
|
+
}
|
|
1037
|
+
return wrapped;
|
|
1038
|
+
};
|
|
1039
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1040
|
+
function retry(fn, options) {
|
|
1041
|
+
const attempts = Math.max(1, Math.trunc(options.attempts));
|
|
1042
|
+
const baseDelay = options.delay === void 0 ? 0 : toMs(options.delay);
|
|
1043
|
+
const maxDelay = options.maxDelay === void 0 ? Infinity : toMs(options.maxDelay);
|
|
1044
|
+
const backoff = options.backoff ?? "fixed";
|
|
1045
|
+
const delayFor = (attempt) => {
|
|
1046
|
+
const raw = backoff === "exponential" ? baseDelay * 2 ** (attempt - 1) : backoff === "linear" ? baseDelay * attempt : baseDelay;
|
|
1047
|
+
return Math.min(raw, maxDelay);
|
|
1048
|
+
};
|
|
1049
|
+
const wrapped = async (...args) => {
|
|
1050
|
+
let last = { kind: "threw", thrown: void 0 };
|
|
1051
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
1052
|
+
last = await attemptCall(fn, args);
|
|
1053
|
+
if (last.kind === "ok") return ok(last.value);
|
|
1054
|
+
const failure = last.kind === "err" ? last.error : last.thrown;
|
|
1055
|
+
if (options.retryIf && !options.retryIf(failure)) break;
|
|
1056
|
+
if (attempt < attempts) {
|
|
1057
|
+
options.onRetry?.({ attempt, failure });
|
|
1058
|
+
const ms = delayFor(attempt);
|
|
1059
|
+
if (ms > 0) await sleep(ms);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
if (last.kind === "err") return last.result;
|
|
1063
|
+
throw last.thrown;
|
|
1064
|
+
};
|
|
1065
|
+
return named(wrapped, fn);
|
|
1066
|
+
}
|
|
1067
|
+
function timeout(fn, after) {
|
|
1068
|
+
const ms = toMs(after);
|
|
1069
|
+
const TIMED_OUT = /* @__PURE__ */ Symbol("timed-out");
|
|
1070
|
+
const wrapped = async (...args) => {
|
|
1071
|
+
let timer;
|
|
1072
|
+
try {
|
|
1073
|
+
const outcome = await Promise.race([
|
|
1074
|
+
attemptCall(fn, args),
|
|
1075
|
+
new Promise((resolve) => {
|
|
1076
|
+
timer = setTimeout(() => resolve(TIMED_OUT), ms);
|
|
1077
|
+
})
|
|
1078
|
+
]);
|
|
1079
|
+
if (outcome === TIMED_OUT) {
|
|
1080
|
+
return err(new TimeoutError({ operation: fn.name || void 0, ms }));
|
|
1081
|
+
}
|
|
1082
|
+
if (outcome.kind === "ok") return ok(outcome.value);
|
|
1083
|
+
if (outcome.kind === "err") return outcome.result;
|
|
1084
|
+
throw outcome.thrown;
|
|
1085
|
+
} finally {
|
|
1086
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
return named(wrapped, fn);
|
|
1090
|
+
}
|
|
1091
|
+
function fallback(fn, onFailure) {
|
|
1092
|
+
const wrapped = async (...args) => {
|
|
1093
|
+
const outcome = await attemptCall(fn, args);
|
|
1094
|
+
if (outcome.kind === "ok") return ok(outcome.value);
|
|
1095
|
+
const failure = outcome.kind === "err" ? outcome.error : new UnexpectedError({ cause: outcome.thrown });
|
|
1096
|
+
const recovered = await attemptCall(onFailure, [failure, ...args]);
|
|
1097
|
+
if (recovered.kind === "ok") return ok(recovered.value);
|
|
1098
|
+
if (recovered.kind === "err") return recovered.result;
|
|
1099
|
+
throw recovered.thrown;
|
|
1100
|
+
};
|
|
1101
|
+
return named(wrapped, fn);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// src/core/index.ts
|
|
1105
|
+
function parseDurationString(input) {
|
|
1106
|
+
const match2 = input.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);
|
|
1107
|
+
if (!match2) return void 0;
|
|
1108
|
+
const value = parseFloat(match2[1]);
|
|
1109
|
+
const unit = match2[2].toLowerCase();
|
|
1110
|
+
const multipliers = { ms: 1, s: 1e3, m: 6e4, h: 36e5, d: 864e5 };
|
|
1111
|
+
return { _tag: "Duration", millis: value * (multipliers[unit] ?? 1) };
|
|
1112
|
+
}
|
|
1113
|
+
function defaultCatchUnexpected(cause) {
|
|
1114
|
+
return new UnexpectedError({ cause });
|
|
1115
|
+
}
|
|
1116
|
+
function ok2(value) {
|
|
1117
|
+
return { ok: true, value };
|
|
1118
|
+
}
|
|
1119
|
+
function err2(error, options) {
|
|
1120
|
+
const cause = options?.cause;
|
|
1121
|
+
return { ok: false, error, ...cause !== void 0 ? { cause } : {} };
|
|
1122
|
+
}
|
|
1123
|
+
function extractErrorTag(error) {
|
|
1124
|
+
if (error == null) return "unknown";
|
|
1125
|
+
if (typeof error === "string") return error.trim() || "unknown";
|
|
1126
|
+
if (typeof error === "object") {
|
|
1127
|
+
const tagged = error;
|
|
1128
|
+
if (typeof tagged._tag === "string") {
|
|
1129
|
+
const trimmed = tagged._tag.trim();
|
|
1130
|
+
if (trimmed) return trimmed;
|
|
1131
|
+
}
|
|
1132
|
+
if (typeof tagged.tag === "string") {
|
|
1133
|
+
const trimmed = tagged.tag.trim();
|
|
1134
|
+
if (trimmed) return trimmed;
|
|
1135
|
+
}
|
|
1136
|
+
if (typeof tagged.code === "string") {
|
|
1137
|
+
const trimmed = tagged.code.trim();
|
|
1138
|
+
if (trimmed) return trimmed;
|
|
1139
|
+
} else if (typeof tagged.code === "number") {
|
|
1140
|
+
return String(tagged.code);
|
|
1141
|
+
}
|
|
1142
|
+
if (error instanceof Error && error.name) {
|
|
1143
|
+
const trimmed = error.name.trim();
|
|
1144
|
+
if (trimmed) return trimmed;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
return "unknown";
|
|
1148
|
+
}
|
|
1149
|
+
function lookupErrorClassification(tag2, errorMeta) {
|
|
1150
|
+
if (!errorMeta || !tag2) return void 0;
|
|
1151
|
+
return errorMeta[tag2];
|
|
1152
|
+
}
|
|
1153
|
+
function extractStepMetadata(options) {
|
|
1154
|
+
const { intent, domain, owner, tags: tags3, stateChanges, emits, calls } = options;
|
|
1155
|
+
if (!intent && !domain && !owner && !tags3?.length && !stateChanges?.length && !emits?.length && !calls?.length) {
|
|
1156
|
+
return void 0;
|
|
1157
|
+
}
|
|
1158
|
+
const metadata = {};
|
|
1159
|
+
if (intent) metadata.intent = intent;
|
|
1160
|
+
if (domain) metadata.domain = domain;
|
|
1161
|
+
if (owner) metadata.owner = owner;
|
|
1162
|
+
if (tags3?.length) metadata.tags = tags3;
|
|
1163
|
+
if (stateChanges?.length) metadata.stateChanges = stateChanges;
|
|
1164
|
+
if (emits?.length) metadata.emits = emits;
|
|
1165
|
+
if (calls?.length) metadata.calls = calls;
|
|
1166
|
+
return metadata;
|
|
1167
|
+
}
|
|
1168
|
+
function buildStepErrorPayload(error, errorMeta, origin, attempt, cumulativeDurationMs) {
|
|
1169
|
+
const tag2 = extractErrorTag(error);
|
|
1170
|
+
const classification = lookupErrorClassification(tag2, errorMeta);
|
|
1171
|
+
const diagnostics = { tag: tag2, origin };
|
|
1172
|
+
if (classification !== void 0) diagnostics.classification = classification;
|
|
1173
|
+
if (attempt !== void 0) diagnostics.attempt = attempt;
|
|
1174
|
+
if (cumulativeDurationMs !== void 0) diagnostics.cumulativeDurationMs = cumulativeDurationMs;
|
|
1175
|
+
return diagnostics;
|
|
1176
|
+
}
|
|
1177
|
+
var STEP_TIMEOUT_MARKER = /* @__PURE__ */ Symbol.for("step_timeout_marker");
|
|
1178
|
+
function isStepTimeoutError(e) {
|
|
1179
|
+
if (typeof e !== "object" || e === null) {
|
|
1180
|
+
return false;
|
|
1181
|
+
}
|
|
1182
|
+
if (e.type === "STEP_TIMEOUT") {
|
|
1183
|
+
return true;
|
|
1184
|
+
}
|
|
1185
|
+
return STEP_TIMEOUT_MARKER in e;
|
|
1186
|
+
}
|
|
1187
|
+
function getStepTimeoutMeta(e) {
|
|
1188
|
+
if (typeof e !== "object" || e === null) {
|
|
1189
|
+
return void 0;
|
|
1190
|
+
}
|
|
1191
|
+
if (e.type === "STEP_TIMEOUT") {
|
|
1192
|
+
const err3 = e;
|
|
1193
|
+
return {
|
|
1194
|
+
timeoutMs: err3.timeoutMs,
|
|
1195
|
+
stepName: err3.stepName,
|
|
1196
|
+
stepKey: err3.stepKey,
|
|
1197
|
+
attempt: err3.attempt
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
if (STEP_TIMEOUT_MARKER in e) {
|
|
1201
|
+
return e[STEP_TIMEOUT_MARKER];
|
|
1202
|
+
}
|
|
1203
|
+
return void 0;
|
|
1204
|
+
}
|
|
1205
|
+
var EARLY_EXIT_SYMBOL = /* @__PURE__ */ Symbol("early-exit");
|
|
1206
|
+
function createEarlyExit(error, meta) {
|
|
1207
|
+
return {
|
|
1208
|
+
[EARLY_EXIT_SYMBOL]: true,
|
|
1209
|
+
error,
|
|
1210
|
+
meta
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
function isEarlyExit(e) {
|
|
1214
|
+
return typeof e === "object" && e !== null && e[EARLY_EXIT_SYMBOL] === true;
|
|
1215
|
+
}
|
|
1216
|
+
var MAPPER_EXCEPTION_SYMBOL = /* @__PURE__ */ Symbol("mapper-exception");
|
|
1217
|
+
function createMapperException(thrown) {
|
|
1218
|
+
return { [MAPPER_EXCEPTION_SYMBOL]: true, thrown };
|
|
1219
|
+
}
|
|
1220
|
+
function isMapperException(e) {
|
|
1221
|
+
return typeof e === "object" && e !== null && e[MAPPER_EXCEPTION_SYMBOL] === true;
|
|
1222
|
+
}
|
|
1223
|
+
function calculateRetryDelay(attempt, options) {
|
|
1224
|
+
const { backoff, initialDelay, maxDelay, jitter } = options;
|
|
1225
|
+
let delay;
|
|
1226
|
+
switch (backoff) {
|
|
1227
|
+
case "fixed":
|
|
1228
|
+
delay = initialDelay;
|
|
1229
|
+
break;
|
|
1230
|
+
case "linear":
|
|
1231
|
+
delay = initialDelay * attempt;
|
|
1232
|
+
break;
|
|
1233
|
+
case "exponential":
|
|
1234
|
+
delay = initialDelay * Math.pow(2, attempt - 1);
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1237
|
+
delay = Math.min(delay, maxDelay);
|
|
1238
|
+
if (jitter) {
|
|
1239
|
+
const jitterAmount = delay * 0.25 * Math.random();
|
|
1240
|
+
delay = delay + jitterAmount;
|
|
1241
|
+
}
|
|
1242
|
+
return Math.floor(delay);
|
|
1243
|
+
}
|
|
1244
|
+
function sleep2(ms) {
|
|
1245
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1246
|
+
}
|
|
1247
|
+
var TIMEOUT_SYMBOL = /* @__PURE__ */ Symbol("timeout");
|
|
1248
|
+
var TIMEOUT_OPTION_SYMBOL = /* @__PURE__ */ Symbol("timeout-option");
|
|
1249
|
+
function isTimeoutOptionMarker(value) {
|
|
1250
|
+
return typeof value === "object" && value !== null && value[TIMEOUT_OPTION_SYMBOL] === true;
|
|
1251
|
+
}
|
|
1252
|
+
async function executeWithTimeout(operation, options, stepInfo, externalSignal) {
|
|
1253
|
+
const controller = new AbortController();
|
|
1254
|
+
const behavior = options.onTimeout ?? "error";
|
|
1255
|
+
const createTimeoutError = () => {
|
|
1256
|
+
if (typeof behavior === "function") {
|
|
1257
|
+
return behavior({
|
|
1258
|
+
name: stepInfo.name,
|
|
1259
|
+
key: stepInfo.key,
|
|
1260
|
+
ms: options.ms
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
return options.error ?? {
|
|
1264
|
+
type: "STEP_TIMEOUT",
|
|
1265
|
+
stepName: stepInfo.name,
|
|
1266
|
+
stepKey: stepInfo.key,
|
|
1267
|
+
timeoutMs: options.ms,
|
|
1268
|
+
attempt: stepInfo.attempt
|
|
1269
|
+
};
|
|
1270
|
+
};
|
|
1271
|
+
let timeoutId;
|
|
1272
|
+
if (externalSignal?.aborted) {
|
|
1273
|
+
controller.abort(externalSignal.reason);
|
|
1274
|
+
}
|
|
1275
|
+
let externalAbortHandler;
|
|
1276
|
+
if (externalSignal && !externalSignal.aborted) {
|
|
1277
|
+
externalAbortHandler = () => controller.abort(externalSignal.reason);
|
|
1278
|
+
externalSignal.addEventListener("abort", externalAbortHandler, { once: true });
|
|
1279
|
+
}
|
|
1280
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1281
|
+
timeoutId = setTimeout(() => {
|
|
1282
|
+
if (behavior !== "disconnect") {
|
|
1283
|
+
controller.abort();
|
|
1284
|
+
}
|
|
1285
|
+
if (behavior === "option") {
|
|
1286
|
+
reject({ [TIMEOUT_OPTION_SYMBOL]: true, ms: options.ms });
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
reject({ [TIMEOUT_SYMBOL]: true, error: createTimeoutError() });
|
|
1290
|
+
}, options.ms);
|
|
1291
|
+
});
|
|
1292
|
+
let operationPromise;
|
|
1293
|
+
if (options.signal) {
|
|
1294
|
+
operationPromise = Promise.resolve(
|
|
1295
|
+
operation(controller.signal)
|
|
1296
|
+
);
|
|
1297
|
+
} else {
|
|
1298
|
+
operationPromise = Promise.resolve(operation());
|
|
1299
|
+
}
|
|
1300
|
+
try {
|
|
1301
|
+
const result = await Promise.race([operationPromise, timeoutPromise]);
|
|
1302
|
+
return result;
|
|
1303
|
+
} catch (error) {
|
|
1304
|
+
if (typeof error === "object" && error !== null && error[TIMEOUT_OPTION_SYMBOL] === true) {
|
|
1305
|
+
throw { [TIMEOUT_OPTION_SYMBOL]: true, ms: options.ms };
|
|
1306
|
+
}
|
|
1307
|
+
if (typeof error === "object" && error !== null && error[TIMEOUT_SYMBOL] === true) {
|
|
1308
|
+
if (behavior === "disconnect") {
|
|
1309
|
+
operationPromise.catch(() => {
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
const errorToThrow = error.error;
|
|
1313
|
+
if (typeof errorToThrow === "object" && errorToThrow !== null && errorToThrow.type !== "STEP_TIMEOUT") {
|
|
1314
|
+
const meta = {
|
|
1315
|
+
timeoutMs: options.ms,
|
|
1316
|
+
stepName: stepInfo.name,
|
|
1317
|
+
stepKey: stepInfo.key,
|
|
1318
|
+
attempt: stepInfo.attempt
|
|
1319
|
+
};
|
|
1320
|
+
if (STEP_TIMEOUT_MARKER in errorToThrow) {
|
|
1321
|
+
errorToThrow[STEP_TIMEOUT_MARKER] = meta;
|
|
1322
|
+
} else {
|
|
1323
|
+
Object.defineProperty(errorToThrow, STEP_TIMEOUT_MARKER, {
|
|
1324
|
+
value: meta,
|
|
1325
|
+
enumerable: false,
|
|
1326
|
+
writable: true,
|
|
1327
|
+
configurable: false
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
throw errorToThrow;
|
|
1332
|
+
}
|
|
1333
|
+
throw error;
|
|
1334
|
+
} finally {
|
|
1335
|
+
clearTimeout(timeoutId);
|
|
1336
|
+
if (externalAbortHandler && externalSignal) {
|
|
1337
|
+
externalSignal.removeEventListener("abort", externalAbortHandler);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
var DEFAULT_RETRY_CONFIG = {
|
|
1342
|
+
backoff: "exponential",
|
|
1343
|
+
initialDelay: 100,
|
|
1344
|
+
maxDelay: 3e4,
|
|
1345
|
+
jitter: true,
|
|
1346
|
+
shouldRetry: () => true,
|
|
1347
|
+
onRetry: () => {
|
|
1348
|
+
}
|
|
1349
|
+
};
|
|
1350
|
+
async function runFn(fnOrDeps, optionsOrFn, maybeOptions) {
|
|
1351
|
+
if (typeof fnOrDeps !== "function") {
|
|
1352
|
+
const deps = fnOrDeps;
|
|
1353
|
+
const boundFn = optionsOrFn;
|
|
1354
|
+
if (typeof boundFn !== "function") {
|
|
1355
|
+
throw new TypeError(
|
|
1356
|
+
"[awaitly] run(deps, fn) requires a callback as the second argument. Example: run({ getUser }, async (s) => s.getUser(id))"
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
const classicRun = runFn;
|
|
1360
|
+
return classicRun(
|
|
1361
|
+
({ step }) => boundFn(bindSteps(deps, step), { step }),
|
|
1362
|
+
maybeOptions
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1365
|
+
const fn = fnOrDeps;
|
|
1366
|
+
const options = optionsOrFn;
|
|
1367
|
+
const {
|
|
1368
|
+
onError,
|
|
1369
|
+
onEvent,
|
|
1370
|
+
catchUnexpected,
|
|
1371
|
+
workflowId: providedWorkflowId,
|
|
1372
|
+
workflowName,
|
|
1373
|
+
context,
|
|
1374
|
+
graph,
|
|
1375
|
+
_workflowSignal
|
|
1376
|
+
} = options && typeof options === "object" ? options : {};
|
|
1377
|
+
const workflowId = providedWorkflowId ?? crypto.randomUUID();
|
|
1378
|
+
const declaredIds = graph ? new Set(
|
|
1379
|
+
Array.isArray(graph) ? graph : graph.states.map((state) => state.semanticId ?? state.id)
|
|
1380
|
+
) : void 0;
|
|
1381
|
+
const declaredPatterns = declaredIds ? [...declaredIds].filter((id) => id.includes("{")).map(
|
|
1382
|
+
(id) => new RegExp(
|
|
1383
|
+
`^${id.replaceAll(/[.*+?^$()[\]\\|]/g, String.raw`\$&`).replaceAll(/\{[^}]*\}/g, ".+")}$`
|
|
1384
|
+
)
|
|
1385
|
+
) : void 0;
|
|
1386
|
+
const assertDeclared = (id, kind) => {
|
|
1387
|
+
if (!declaredIds || declaredIds.has(id)) return;
|
|
1388
|
+
if (declaredPatterns?.some((re) => re.test(id))) return;
|
|
1389
|
+
throw new Error(
|
|
1390
|
+
`[awaitly] ${kind} id "${id}" is not in the declared workflow graph. Declared ids: ${[...declaredIds].join(", ")}. Either add it to the graph or remove the graph option.`
|
|
1391
|
+
);
|
|
1392
|
+
};
|
|
1393
|
+
const effectiveCatchUnexpected = catchUnexpected ?? defaultCatchUnexpected;
|
|
1394
|
+
const activeScopeStack = [];
|
|
1395
|
+
let stepIdCounter = 0;
|
|
1396
|
+
const generateStepId = (stepKey) => {
|
|
1397
|
+
return stepKey ?? `step_${++stepIdCounter}`;
|
|
1398
|
+
};
|
|
1399
|
+
const emitEvent = (event) => {
|
|
1400
|
+
const eventWithContext = event.context !== void 0 || context === void 0 ? event : { ...event, context };
|
|
1401
|
+
const eventWithName = workflowName !== void 0 && eventWithContext.workflowName === void 0 ? { ...eventWithContext, workflowName } : eventWithContext;
|
|
1402
|
+
if (eventWithName.type === "step_success") {
|
|
1403
|
+
const stepId = eventWithName.stepId;
|
|
1404
|
+
for (let i = activeScopeStack.length - 1; i >= 0; i--) {
|
|
1405
|
+
const scope = activeScopeStack[i];
|
|
1406
|
+
if (scope.type === "race" && !scope.winnerId) {
|
|
1407
|
+
scope.winnerId = stepId;
|
|
1408
|
+
break;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
onEvent?.(eventWithName, context);
|
|
1413
|
+
};
|
|
1414
|
+
const earlyExit = createEarlyExit;
|
|
1415
|
+
const isEarlyExitE = (e) => isEarlyExit(e);
|
|
1416
|
+
const wrapForStep = (error, _meta) => {
|
|
1417
|
+
return error;
|
|
1418
|
+
};
|
|
1419
|
+
const isResultLike = (value) => {
|
|
1420
|
+
if (typeof value === "function") return false;
|
|
1421
|
+
if (value && typeof value === "object" && "ok" in value) return true;
|
|
1422
|
+
if (value && typeof value === "object" && "then" in value && typeof value.then === "function") return true;
|
|
1423
|
+
return false;
|
|
1424
|
+
};
|
|
1425
|
+
try {
|
|
1426
|
+
let normalizeParallelOperations2 = function(rawOperations) {
|
|
1427
|
+
const out = {};
|
|
1428
|
+
for (const [key, value2] of Object.entries(rawOperations)) {
|
|
1429
|
+
if (typeof value2 === "function") {
|
|
1430
|
+
out[key] = value2;
|
|
1431
|
+
} else if (value2 && typeof value2 === "object" && "fn" in value2) {
|
|
1432
|
+
out[key] = value2.fn;
|
|
1433
|
+
} else {
|
|
1434
|
+
throw new TypeError(`step.all: operation "${key}" must be a function or { fn, errors? } object`);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
return out;
|
|
1438
|
+
}, executeParallelArray2 = function(name, operation) {
|
|
1439
|
+
const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1440
|
+
return (async () => {
|
|
1441
|
+
const startTime = performance.now();
|
|
1442
|
+
let scopeEnded = false;
|
|
1443
|
+
activeScopeStack.push({ scopeId, type: "parallel" });
|
|
1444
|
+
const emitScopeEnd = () => {
|
|
1445
|
+
if (scopeEnded) return;
|
|
1446
|
+
scopeEnded = true;
|
|
1447
|
+
const idx = activeScopeStack.findIndex((s) => s.scopeId === scopeId);
|
|
1448
|
+
if (idx !== -1) activeScopeStack.splice(idx, 1);
|
|
1449
|
+
emitEvent({
|
|
1450
|
+
type: "scope_end",
|
|
1451
|
+
workflowId,
|
|
1452
|
+
scopeId,
|
|
1453
|
+
ts: Date.now(),
|
|
1454
|
+
durationMs: performance.now() - startTime
|
|
1455
|
+
});
|
|
1456
|
+
};
|
|
1457
|
+
emitEvent({
|
|
1458
|
+
type: "scope_start",
|
|
1459
|
+
workflowId,
|
|
1460
|
+
scopeId,
|
|
1461
|
+
scopeType: "parallel",
|
|
1462
|
+
name,
|
|
1463
|
+
ts: Date.now()
|
|
1464
|
+
});
|
|
1465
|
+
try {
|
|
1466
|
+
const result = await operation();
|
|
1467
|
+
emitScopeEnd();
|
|
1468
|
+
if (!result.ok) {
|
|
1469
|
+
onError?.(result.error, name, context);
|
|
1470
|
+
throw earlyExit(result.error, {
|
|
1471
|
+
origin: "result",
|
|
1472
|
+
resultCause: result.cause
|
|
1473
|
+
});
|
|
1474
|
+
}
|
|
1475
|
+
return result.value;
|
|
1476
|
+
} catch (error) {
|
|
1477
|
+
emitScopeEnd();
|
|
1478
|
+
throw error;
|
|
1479
|
+
}
|
|
1480
|
+
})();
|
|
1481
|
+
}, executeParallelNamed2 = function(operations, options2) {
|
|
1482
|
+
const keys = Object.keys(operations);
|
|
1483
|
+
const name = options2.name ?? `Parallel(${keys.join(", ")})`;
|
|
1484
|
+
const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1485
|
+
return (async () => {
|
|
1486
|
+
const startTime = performance.now();
|
|
1487
|
+
let scopeEnded = false;
|
|
1488
|
+
activeScopeStack.push({ scopeId, type: "parallel" });
|
|
1489
|
+
const emitScopeEnd = () => {
|
|
1490
|
+
if (scopeEnded) return;
|
|
1491
|
+
scopeEnded = true;
|
|
1492
|
+
const idx = activeScopeStack.findIndex((s) => s.scopeId === scopeId);
|
|
1493
|
+
if (idx !== -1) activeScopeStack.splice(idx, 1);
|
|
1494
|
+
emitEvent({
|
|
1495
|
+
type: "scope_end",
|
|
1496
|
+
workflowId,
|
|
1497
|
+
scopeId,
|
|
1498
|
+
ts: Date.now(),
|
|
1499
|
+
durationMs: performance.now() - startTime
|
|
1500
|
+
});
|
|
1501
|
+
};
|
|
1502
|
+
emitEvent({
|
|
1503
|
+
type: "scope_start",
|
|
1504
|
+
workflowId,
|
|
1505
|
+
scopeId,
|
|
1506
|
+
scopeType: "parallel",
|
|
1507
|
+
name,
|
|
1508
|
+
ts: Date.now()
|
|
1509
|
+
});
|
|
1510
|
+
try {
|
|
1511
|
+
const results = await new Promise((resolve) => {
|
|
1512
|
+
if (keys.length === 0) {
|
|
1513
|
+
resolve([]);
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
let settled = false;
|
|
1517
|
+
let pendingCount = keys.length;
|
|
1518
|
+
const resultArray = new Array(keys.length);
|
|
1519
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1520
|
+
const key = keys[i];
|
|
1521
|
+
const index = i;
|
|
1522
|
+
Promise.resolve(operations[key]()).catch((reason) => err2(
|
|
1523
|
+
{ type: "PROMISE_REJECTED", cause: reason },
|
|
1524
|
+
{ cause: { type: "PROMISE_REJECTION", reason } }
|
|
1525
|
+
)).then((result) => {
|
|
1526
|
+
if (settled) return;
|
|
1527
|
+
if (!result.ok) {
|
|
1528
|
+
settled = true;
|
|
1529
|
+
resolve([{ key, result }]);
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
resultArray[index] = { key, result };
|
|
1533
|
+
pendingCount--;
|
|
1534
|
+
if (pendingCount === 0) {
|
|
1535
|
+
resolve(resultArray);
|
|
1536
|
+
}
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1540
|
+
emitScopeEnd();
|
|
1541
|
+
const output = {};
|
|
1542
|
+
for (const { key, result } of results) {
|
|
1543
|
+
if (!result.ok) {
|
|
1544
|
+
onError?.(result.error, key, context);
|
|
1545
|
+
throw earlyExit(result.error, {
|
|
1546
|
+
origin: "result",
|
|
1547
|
+
resultCause: result.cause
|
|
1548
|
+
});
|
|
1549
|
+
}
|
|
1550
|
+
output[key] = result.value;
|
|
1551
|
+
}
|
|
1552
|
+
return output;
|
|
1553
|
+
} catch (error) {
|
|
1554
|
+
emitScopeEnd();
|
|
1555
|
+
throw error;
|
|
1556
|
+
}
|
|
1557
|
+
})();
|
|
1558
|
+
};
|
|
1559
|
+
var normalizeParallelOperations = normalizeParallelOperations2, executeParallelArray = executeParallelArray2, executeParallelNamed = executeParallelNamed2;
|
|
1560
|
+
const stepFn = (id, operationOrResult, stepOptions2) => {
|
|
1561
|
+
return (async () => {
|
|
1562
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
1563
|
+
throw new Error(
|
|
1564
|
+
'[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))'
|
|
1565
|
+
);
|
|
1566
|
+
}
|
|
1567
|
+
assertDeclared(id, "step");
|
|
1568
|
+
const parsedOptions = stepOptions2 ?? {};
|
|
1569
|
+
const stepMetadata = extractStepMetadata(parsedOptions);
|
|
1570
|
+
const stepName = id;
|
|
1571
|
+
const stepKey = parsedOptions.key ?? id;
|
|
1572
|
+
const explicitKey = parsedOptions.key ?? id;
|
|
1573
|
+
const { description: stepDescription, retry: retryConfig, timeout: timeoutConfig } = parsedOptions;
|
|
1574
|
+
const stepId = generateStepId(stepKey);
|
|
1575
|
+
const hasEventListeners = onEvent;
|
|
1576
|
+
const overallStartTime = hasEventListeners ? performance.now() : 0;
|
|
1577
|
+
const isDirectResult = isResultLike(operationOrResult);
|
|
1578
|
+
const operation = isDirectResult ? () => operationOrResult : operationOrResult;
|
|
1579
|
+
const maxAttempts = Math.max(1, retryConfig?.attempts ?? 1);
|
|
1580
|
+
const effectiveRetry = {
|
|
1581
|
+
attempts: maxAttempts,
|
|
1582
|
+
backoff: retryConfig?.backoff ?? DEFAULT_RETRY_CONFIG.backoff,
|
|
1583
|
+
initialDelay: retryConfig?.initialDelay ?? DEFAULT_RETRY_CONFIG.initialDelay,
|
|
1584
|
+
maxDelay: retryConfig?.maxDelay ?? DEFAULT_RETRY_CONFIG.maxDelay,
|
|
1585
|
+
jitter: retryConfig?.jitter ?? DEFAULT_RETRY_CONFIG.jitter,
|
|
1586
|
+
shouldRetry: retryConfig?.shouldRetry ?? DEFAULT_RETRY_CONFIG.shouldRetry,
|
|
1587
|
+
onRetry: retryConfig?.onRetry ?? DEFAULT_RETRY_CONFIG.onRetry
|
|
1588
|
+
};
|
|
1589
|
+
if (onEvent) {
|
|
1590
|
+
emitEvent({
|
|
1591
|
+
type: "step_start",
|
|
1592
|
+
workflowId,
|
|
1593
|
+
stepId,
|
|
1594
|
+
stepKey,
|
|
1595
|
+
name: stepName,
|
|
1596
|
+
description: stepDescription,
|
|
1597
|
+
ts: Date.now(),
|
|
1598
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
let lastResult;
|
|
1602
|
+
for (let attempt = 1; attempt <= effectiveRetry.attempts; attempt++) {
|
|
1603
|
+
const attemptStartTime = hasEventListeners ? performance.now() : 0;
|
|
1604
|
+
try {
|
|
1605
|
+
let result;
|
|
1606
|
+
if (timeoutConfig) {
|
|
1607
|
+
result = await executeWithTimeout(
|
|
1608
|
+
operation,
|
|
1609
|
+
timeoutConfig,
|
|
1610
|
+
{ name: stepName, key: stepKey, attempt },
|
|
1611
|
+
_workflowSignal
|
|
1612
|
+
);
|
|
1613
|
+
} else {
|
|
1614
|
+
result = await operation();
|
|
1615
|
+
}
|
|
1616
|
+
if (result.ok) {
|
|
1617
|
+
const durationMs = performance.now() - overallStartTime;
|
|
1618
|
+
emitEvent({
|
|
1619
|
+
type: "step_success",
|
|
1620
|
+
workflowId,
|
|
1621
|
+
stepId,
|
|
1622
|
+
stepKey,
|
|
1623
|
+
name: stepName,
|
|
1624
|
+
description: stepDescription,
|
|
1625
|
+
ts: Date.now(),
|
|
1626
|
+
durationMs,
|
|
1627
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1628
|
+
});
|
|
1629
|
+
if (explicitKey) {
|
|
1630
|
+
emitEvent({
|
|
1631
|
+
type: "step_complete",
|
|
1632
|
+
workflowId,
|
|
1633
|
+
stepKey: explicitKey,
|
|
1634
|
+
name: stepName,
|
|
1635
|
+
description: stepDescription,
|
|
1636
|
+
ts: Date.now(),
|
|
1637
|
+
durationMs,
|
|
1638
|
+
result,
|
|
1639
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
return result.value;
|
|
1643
|
+
}
|
|
1644
|
+
lastResult = result;
|
|
1645
|
+
if (attempt < effectiveRetry.attempts && effectiveRetry.shouldRetry(result.error, attempt)) {
|
|
1646
|
+
const delay = calculateRetryDelay(attempt, effectiveRetry);
|
|
1647
|
+
emitEvent({
|
|
1648
|
+
type: "step_retry",
|
|
1649
|
+
workflowId,
|
|
1650
|
+
stepId,
|
|
1651
|
+
stepKey,
|
|
1652
|
+
name: stepName,
|
|
1653
|
+
ts: Date.now(),
|
|
1654
|
+
attempt: attempt + 1,
|
|
1655
|
+
maxAttempts: effectiveRetry.attempts,
|
|
1656
|
+
delayMs: delay,
|
|
1657
|
+
error: result.error,
|
|
1658
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1659
|
+
diagnostics: buildStepErrorPayload(result.error, parsedOptions.errorMeta, "result", attempt, performance.now() - overallStartTime)
|
|
1660
|
+
});
|
|
1661
|
+
effectiveRetry.onRetry(result.error, attempt, delay);
|
|
1662
|
+
await sleep2(delay);
|
|
1663
|
+
continue;
|
|
1664
|
+
}
|
|
1665
|
+
if (effectiveRetry.attempts > 1) {
|
|
1666
|
+
emitEvent({
|
|
1667
|
+
type: "step_retries_exhausted",
|
|
1668
|
+
workflowId,
|
|
1669
|
+
stepId,
|
|
1670
|
+
stepKey,
|
|
1671
|
+
name: stepName,
|
|
1672
|
+
ts: Date.now(),
|
|
1673
|
+
durationMs: performance.now() - overallStartTime,
|
|
1674
|
+
attempts: attempt,
|
|
1675
|
+
lastError: result.error,
|
|
1676
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1677
|
+
diagnostics: buildStepErrorPayload(result.error, parsedOptions.errorMeta, "result", attempt, performance.now() - overallStartTime)
|
|
1678
|
+
});
|
|
1679
|
+
}
|
|
1680
|
+
break;
|
|
1681
|
+
} catch (thrown) {
|
|
1682
|
+
const durationMs = performance.now() - attemptStartTime;
|
|
1683
|
+
if (isTimeoutOptionMarker(thrown)) {
|
|
1684
|
+
const timeoutMs = thrown.ms;
|
|
1685
|
+
emitEvent({
|
|
1686
|
+
type: "step_timeout",
|
|
1687
|
+
workflowId,
|
|
1688
|
+
stepId,
|
|
1689
|
+
stepKey,
|
|
1690
|
+
name: stepName,
|
|
1691
|
+
ts: Date.now(),
|
|
1692
|
+
timeoutMs,
|
|
1693
|
+
attempt,
|
|
1694
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1695
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "timeout", attempt)
|
|
1696
|
+
});
|
|
1697
|
+
emitEvent({
|
|
1698
|
+
type: "step_success",
|
|
1699
|
+
workflowId,
|
|
1700
|
+
stepId,
|
|
1701
|
+
stepKey,
|
|
1702
|
+
name: stepName,
|
|
1703
|
+
description: stepDescription,
|
|
1704
|
+
ts: Date.now(),
|
|
1705
|
+
durationMs: performance.now() - overallStartTime,
|
|
1706
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1707
|
+
});
|
|
1708
|
+
if (explicitKey) {
|
|
1709
|
+
emitEvent({
|
|
1710
|
+
type: "step_complete",
|
|
1711
|
+
workflowId,
|
|
1712
|
+
stepKey: explicitKey,
|
|
1713
|
+
name: stepName,
|
|
1714
|
+
description: stepDescription,
|
|
1715
|
+
ts: Date.now(),
|
|
1716
|
+
durationMs: performance.now() - overallStartTime,
|
|
1717
|
+
result: ok2(void 0),
|
|
1718
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
return void 0;
|
|
1722
|
+
}
|
|
1723
|
+
if (isEarlyExitE(thrown)) {
|
|
1724
|
+
emitEvent({
|
|
1725
|
+
type: "step_aborted",
|
|
1726
|
+
workflowId,
|
|
1727
|
+
stepId,
|
|
1728
|
+
stepKey,
|
|
1729
|
+
name: stepName,
|
|
1730
|
+
description: stepDescription,
|
|
1731
|
+
ts: Date.now(),
|
|
1732
|
+
durationMs,
|
|
1733
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1734
|
+
});
|
|
1735
|
+
throw thrown;
|
|
1736
|
+
}
|
|
1737
|
+
if (isStepTimeoutError(thrown)) {
|
|
1738
|
+
const timeoutMeta = getStepTimeoutMeta(thrown);
|
|
1739
|
+
const timeoutMs = timeoutConfig?.ms ?? timeoutMeta?.timeoutMs ?? 0;
|
|
1740
|
+
emitEvent({
|
|
1741
|
+
type: "step_timeout",
|
|
1742
|
+
workflowId,
|
|
1743
|
+
stepId,
|
|
1744
|
+
stepKey,
|
|
1745
|
+
name: stepName,
|
|
1746
|
+
ts: Date.now(),
|
|
1747
|
+
timeoutMs,
|
|
1748
|
+
attempt,
|
|
1749
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1750
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "timeout", attempt)
|
|
1751
|
+
});
|
|
1752
|
+
if (attempt < effectiveRetry.attempts && effectiveRetry.shouldRetry(thrown, attempt)) {
|
|
1753
|
+
const delay = calculateRetryDelay(attempt, effectiveRetry);
|
|
1754
|
+
emitEvent({
|
|
1755
|
+
type: "step_retry",
|
|
1756
|
+
workflowId,
|
|
1757
|
+
stepId,
|
|
1758
|
+
stepKey,
|
|
1759
|
+
name: stepName,
|
|
1760
|
+
ts: Date.now(),
|
|
1761
|
+
attempt: attempt + 1,
|
|
1762
|
+
maxAttempts: effectiveRetry.attempts,
|
|
1763
|
+
delayMs: delay,
|
|
1764
|
+
error: thrown,
|
|
1765
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1766
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "timeout", attempt, performance.now() - overallStartTime)
|
|
1767
|
+
});
|
|
1768
|
+
effectiveRetry.onRetry(thrown, attempt, delay);
|
|
1769
|
+
await sleep2(delay);
|
|
1770
|
+
continue;
|
|
1771
|
+
}
|
|
1772
|
+
if (effectiveRetry.attempts > 1) {
|
|
1773
|
+
emitEvent({
|
|
1774
|
+
type: "step_retries_exhausted",
|
|
1775
|
+
workflowId,
|
|
1776
|
+
stepId,
|
|
1777
|
+
stepKey,
|
|
1778
|
+
name: stepName,
|
|
1779
|
+
ts: Date.now(),
|
|
1780
|
+
durationMs: performance.now() - overallStartTime,
|
|
1781
|
+
attempts: attempt,
|
|
1782
|
+
lastError: thrown,
|
|
1783
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1784
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "timeout", attempt, performance.now() - overallStartTime)
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
const totalDurationMs3 = performance.now() - overallStartTime;
|
|
1788
|
+
emitEvent({
|
|
1789
|
+
type: "step_error",
|
|
1790
|
+
workflowId,
|
|
1791
|
+
stepId,
|
|
1792
|
+
stepKey,
|
|
1793
|
+
name: stepName,
|
|
1794
|
+
description: stepDescription,
|
|
1795
|
+
ts: Date.now(),
|
|
1796
|
+
durationMs: totalDurationMs3,
|
|
1797
|
+
error: thrown,
|
|
1798
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1799
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "timeout", attempt, totalDurationMs3)
|
|
1800
|
+
});
|
|
1801
|
+
if (explicitKey) {
|
|
1802
|
+
emitEvent({
|
|
1803
|
+
type: "step_complete",
|
|
1804
|
+
workflowId,
|
|
1805
|
+
stepKey: explicitKey,
|
|
1806
|
+
name: stepName,
|
|
1807
|
+
description: stepDescription,
|
|
1808
|
+
ts: Date.now(),
|
|
1809
|
+
durationMs: totalDurationMs3,
|
|
1810
|
+
result: err2(thrown, { cause: thrown }),
|
|
1811
|
+
meta: { origin: "throw", thrown },
|
|
1812
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
onError?.(thrown, stepName, context);
|
|
1816
|
+
throw earlyExit(thrown, { origin: "throw", thrown });
|
|
1817
|
+
}
|
|
1818
|
+
if (attempt < effectiveRetry.attempts && effectiveRetry.shouldRetry(thrown, attempt)) {
|
|
1819
|
+
const delay = calculateRetryDelay(attempt, effectiveRetry);
|
|
1820
|
+
emitEvent({
|
|
1821
|
+
type: "step_retry",
|
|
1822
|
+
workflowId,
|
|
1823
|
+
stepId,
|
|
1824
|
+
stepKey,
|
|
1825
|
+
name: stepName,
|
|
1826
|
+
ts: Date.now(),
|
|
1827
|
+
attempt: attempt + 1,
|
|
1828
|
+
maxAttempts: effectiveRetry.attempts,
|
|
1829
|
+
delayMs: delay,
|
|
1830
|
+
error: thrown,
|
|
1831
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1832
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "throw", attempt, performance.now() - overallStartTime)
|
|
1833
|
+
});
|
|
1834
|
+
effectiveRetry.onRetry(thrown, attempt, delay);
|
|
1835
|
+
await sleep2(delay);
|
|
1836
|
+
continue;
|
|
1837
|
+
}
|
|
1838
|
+
if (effectiveRetry.attempts > 1 && !isStepTimeoutError(thrown)) {
|
|
1839
|
+
emitEvent({
|
|
1840
|
+
type: "step_retries_exhausted",
|
|
1841
|
+
workflowId,
|
|
1842
|
+
stepId,
|
|
1843
|
+
stepKey,
|
|
1844
|
+
name: stepName,
|
|
1845
|
+
ts: Date.now(),
|
|
1846
|
+
durationMs: performance.now() - overallStartTime,
|
|
1847
|
+
attempts: attempt,
|
|
1848
|
+
lastError: thrown,
|
|
1849
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1850
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "throw", attempt, performance.now() - overallStartTime)
|
|
1851
|
+
});
|
|
1852
|
+
}
|
|
1853
|
+
const totalDurationMs2 = performance.now() - overallStartTime;
|
|
1854
|
+
let mappedError;
|
|
1855
|
+
try {
|
|
1856
|
+
mappedError = effectiveCatchUnexpected(thrown);
|
|
1857
|
+
} catch (mapperError) {
|
|
1858
|
+
throw createMapperException(mapperError);
|
|
1859
|
+
}
|
|
1860
|
+
emitEvent({
|
|
1861
|
+
type: "step_error",
|
|
1862
|
+
workflowId,
|
|
1863
|
+
stepId,
|
|
1864
|
+
stepKey,
|
|
1865
|
+
name: stepName,
|
|
1866
|
+
description: stepDescription,
|
|
1867
|
+
ts: Date.now(),
|
|
1868
|
+
durationMs: totalDurationMs2,
|
|
1869
|
+
error: mappedError,
|
|
1870
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1871
|
+
diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, "throw", attempt, totalDurationMs2)
|
|
1872
|
+
});
|
|
1873
|
+
if (explicitKey) {
|
|
1874
|
+
emitEvent({
|
|
1875
|
+
type: "step_complete",
|
|
1876
|
+
workflowId,
|
|
1877
|
+
stepKey: explicitKey,
|
|
1878
|
+
name: stepName,
|
|
1879
|
+
description: stepDescription,
|
|
1880
|
+
ts: Date.now(),
|
|
1881
|
+
durationMs: totalDurationMs2,
|
|
1882
|
+
result: err2(mappedError, { cause: thrown }),
|
|
1883
|
+
meta: { origin: "throw", thrown },
|
|
1884
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
onError?.(mappedError, stepName, context);
|
|
1888
|
+
throw earlyExit(mappedError, { origin: "throw", thrown });
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
const errorResult = lastResult;
|
|
1892
|
+
const totalDurationMs = performance.now() - overallStartTime;
|
|
1893
|
+
const wrappedError = wrapForStep(errorResult.error, {
|
|
1894
|
+
origin: "result",
|
|
1895
|
+
resultCause: errorResult.cause
|
|
1896
|
+
});
|
|
1897
|
+
emitEvent({
|
|
1898
|
+
type: "step_error",
|
|
1899
|
+
workflowId,
|
|
1900
|
+
stepId,
|
|
1901
|
+
stepKey,
|
|
1902
|
+
name: stepName,
|
|
1903
|
+
description: stepDescription,
|
|
1904
|
+
ts: Date.now(),
|
|
1905
|
+
durationMs: totalDurationMs,
|
|
1906
|
+
error: wrappedError,
|
|
1907
|
+
...stepMetadata && { metadata: stepMetadata },
|
|
1908
|
+
diagnostics: buildStepErrorPayload(errorResult.error, parsedOptions.errorMeta, "result", effectiveRetry.attempts, totalDurationMs)
|
|
1909
|
+
});
|
|
1910
|
+
if (explicitKey) {
|
|
1911
|
+
emitEvent({
|
|
1912
|
+
type: "step_complete",
|
|
1913
|
+
workflowId,
|
|
1914
|
+
stepKey: explicitKey,
|
|
1915
|
+
name: stepName,
|
|
1916
|
+
description: stepDescription,
|
|
1917
|
+
ts: Date.now(),
|
|
1918
|
+
durationMs: totalDurationMs,
|
|
1919
|
+
result: errorResult,
|
|
1920
|
+
meta: { origin: "result", resultCause: errorResult.cause },
|
|
1921
|
+
...stepMetadata && { metadata: stepMetadata }
|
|
1922
|
+
});
|
|
1923
|
+
}
|
|
1924
|
+
onError?.(wrappedError, stepName, context);
|
|
1925
|
+
throw earlyExit(wrappedError, {
|
|
1926
|
+
origin: "result",
|
|
1927
|
+
resultCause: errorResult.cause
|
|
1928
|
+
});
|
|
1929
|
+
})();
|
|
1930
|
+
};
|
|
1931
|
+
stepFn.try = (id, operation, opts) => {
|
|
1932
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
1933
|
+
throw new Error(
|
|
1934
|
+
'[awaitly] step.try() requires an explicit string ID as the first argument. Example: step.try("parse", () => JSON.parse(str), { error: "PARSE_ERROR" })'
|
|
1935
|
+
);
|
|
1936
|
+
}
|
|
1937
|
+
assertDeclared(id, "step");
|
|
1938
|
+
const mapToError = "error" in opts ? () => opts.error : opts.onError;
|
|
1939
|
+
if (opts.retry || opts.timeout) {
|
|
1940
|
+
return stepFn.retry(
|
|
1941
|
+
id,
|
|
1942
|
+
async () => {
|
|
1943
|
+
try {
|
|
1944
|
+
return ok2(await operation());
|
|
1945
|
+
} catch (cause) {
|
|
1946
|
+
return err2(mapToError(cause), { cause });
|
|
1947
|
+
}
|
|
1948
|
+
},
|
|
1949
|
+
{
|
|
1950
|
+
attempts: opts.retry?.attempts ?? 1,
|
|
1951
|
+
...opts.retry ?? {},
|
|
1952
|
+
key: opts.key,
|
|
1953
|
+
timeout: opts.timeout
|
|
1954
|
+
}
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1957
|
+
const stepKey = opts.key ?? id;
|
|
1958
|
+
const stepName = id;
|
|
1959
|
+
const stepId = id;
|
|
1960
|
+
const hasEventListeners = onEvent;
|
|
1961
|
+
return (async () => {
|
|
1962
|
+
const startTime = hasEventListeners ? performance.now() : 0;
|
|
1963
|
+
if (onEvent) {
|
|
1964
|
+
emitEvent({
|
|
1965
|
+
type: "step_start",
|
|
1966
|
+
workflowId,
|
|
1967
|
+
stepId,
|
|
1968
|
+
stepKey,
|
|
1969
|
+
name: stepName,
|
|
1970
|
+
ts: Date.now()
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
try {
|
|
1974
|
+
const value2 = await operation();
|
|
1975
|
+
const durationMs = performance.now() - startTime;
|
|
1976
|
+
emitEvent({
|
|
1977
|
+
type: "step_success",
|
|
1978
|
+
workflowId,
|
|
1979
|
+
stepId,
|
|
1980
|
+
stepKey,
|
|
1981
|
+
name: stepName,
|
|
1982
|
+
ts: Date.now(),
|
|
1983
|
+
durationMs
|
|
1984
|
+
});
|
|
1985
|
+
if (stepKey) {
|
|
1986
|
+
emitEvent({
|
|
1987
|
+
type: "step_complete",
|
|
1988
|
+
workflowId,
|
|
1989
|
+
stepKey,
|
|
1990
|
+
name: stepName,
|
|
1991
|
+
ts: Date.now(),
|
|
1992
|
+
durationMs,
|
|
1993
|
+
result: ok2(value2)
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1996
|
+
return value2;
|
|
1997
|
+
} catch (error) {
|
|
1998
|
+
const mapped = mapToError(error);
|
|
1999
|
+
const durationMs = performance.now() - startTime;
|
|
2000
|
+
const wrappedError = wrapForStep(mapped, { origin: "throw", thrown: error });
|
|
2001
|
+
emitEvent({
|
|
2002
|
+
type: "step_error",
|
|
2003
|
+
workflowId,
|
|
2004
|
+
stepId,
|
|
2005
|
+
stepKey,
|
|
2006
|
+
name: stepName,
|
|
2007
|
+
ts: Date.now(),
|
|
2008
|
+
durationMs,
|
|
2009
|
+
error: wrappedError
|
|
2010
|
+
});
|
|
2011
|
+
if (stepKey) {
|
|
2012
|
+
emitEvent({
|
|
2013
|
+
type: "step_complete",
|
|
2014
|
+
workflowId,
|
|
2015
|
+
stepKey,
|
|
2016
|
+
name: stepName,
|
|
2017
|
+
ts: Date.now(),
|
|
2018
|
+
durationMs,
|
|
2019
|
+
result: err2(mapped, { cause: error }),
|
|
2020
|
+
meta: { origin: "throw", thrown: error }
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
onError?.(wrappedError, stepName, context);
|
|
2024
|
+
throw earlyExit(wrappedError, { origin: "throw", thrown: error });
|
|
2025
|
+
}
|
|
2026
|
+
})();
|
|
2027
|
+
};
|
|
2028
|
+
stepFn.fromResult = (id, operation, opts) => {
|
|
2029
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
2030
|
+
throw new Error(
|
|
2031
|
+
'[awaitly] step.fromResult() requires an explicit string ID as the first argument. Example: step.fromResult("callProvider", () => callProvider(input), { onError: (e) => ({ type: "FAILED" }) })'
|
|
2032
|
+
);
|
|
2033
|
+
}
|
|
2034
|
+
assertDeclared(id, "step");
|
|
2035
|
+
const stepKey = opts.key ?? id;
|
|
2036
|
+
const stepName = id;
|
|
2037
|
+
const stepId = id;
|
|
2038
|
+
const mapToError = "error" in opts ? () => opts.error : opts.onError;
|
|
2039
|
+
const hasEventListeners = onEvent;
|
|
2040
|
+
return (async () => {
|
|
2041
|
+
const startTime = hasEventListeners ? performance.now() : 0;
|
|
2042
|
+
if (onEvent) {
|
|
2043
|
+
emitEvent({
|
|
2044
|
+
type: "step_start",
|
|
2045
|
+
workflowId,
|
|
2046
|
+
stepId,
|
|
2047
|
+
stepKey,
|
|
2048
|
+
name: stepName,
|
|
2049
|
+
ts: Date.now()
|
|
2050
|
+
});
|
|
2051
|
+
}
|
|
2052
|
+
const result = await operation();
|
|
2053
|
+
if (result.ok) {
|
|
2054
|
+
const durationMs = performance.now() - startTime;
|
|
2055
|
+
emitEvent({
|
|
2056
|
+
type: "step_success",
|
|
2057
|
+
workflowId,
|
|
2058
|
+
stepId,
|
|
2059
|
+
stepKey,
|
|
2060
|
+
name: stepName,
|
|
2061
|
+
ts: Date.now(),
|
|
2062
|
+
durationMs
|
|
2063
|
+
});
|
|
2064
|
+
if (stepKey) {
|
|
2065
|
+
emitEvent({
|
|
2066
|
+
type: "step_complete",
|
|
2067
|
+
workflowId,
|
|
2068
|
+
stepKey,
|
|
2069
|
+
name: stepName,
|
|
2070
|
+
ts: Date.now(),
|
|
2071
|
+
durationMs,
|
|
2072
|
+
result: ok2(result.value)
|
|
2073
|
+
});
|
|
2074
|
+
}
|
|
2075
|
+
return result.value;
|
|
2076
|
+
} else {
|
|
2077
|
+
const mapped = mapToError(result.error);
|
|
2078
|
+
const durationMs = performance.now() - startTime;
|
|
2079
|
+
const wrappedError = wrapForStep(mapped, {
|
|
2080
|
+
origin: "result",
|
|
2081
|
+
resultCause: result.error
|
|
2082
|
+
});
|
|
2083
|
+
emitEvent({
|
|
2084
|
+
type: "step_error",
|
|
2085
|
+
workflowId,
|
|
2086
|
+
stepId,
|
|
2087
|
+
stepKey,
|
|
2088
|
+
name: stepName,
|
|
2089
|
+
ts: Date.now(),
|
|
2090
|
+
durationMs,
|
|
2091
|
+
error: wrappedError
|
|
2092
|
+
});
|
|
2093
|
+
if (stepKey) {
|
|
2094
|
+
emitEvent({
|
|
2095
|
+
type: "step_complete",
|
|
2096
|
+
workflowId,
|
|
2097
|
+
stepKey,
|
|
2098
|
+
name: stepName,
|
|
2099
|
+
ts: Date.now(),
|
|
2100
|
+
durationMs,
|
|
2101
|
+
result: err2(mapped, { cause: result.error }),
|
|
2102
|
+
meta: { origin: "result", resultCause: result.error }
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
onError?.(wrappedError, stepName, context);
|
|
2106
|
+
throw earlyExit(wrappedError, {
|
|
2107
|
+
origin: "result",
|
|
2108
|
+
resultCause: result.error
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
})();
|
|
2112
|
+
};
|
|
2113
|
+
stepFn.fromNullable = (id, operation, onNull, options2) => {
|
|
2114
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
2115
|
+
throw new Error(
|
|
2116
|
+
'[awaitly] step.fromNullable() requires an explicit string ID as the first argument. Example: step.fromNullable("getUser", () => db.find(id), () => ({ type: "NOT_FOUND" }))'
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
return stepFn(
|
|
2120
|
+
id,
|
|
2121
|
+
async () => {
|
|
2122
|
+
const value2 = await operation();
|
|
2123
|
+
return value2 != null ? ok2(value2) : err2(onNull());
|
|
2124
|
+
},
|
|
2125
|
+
options2
|
|
2126
|
+
);
|
|
2127
|
+
};
|
|
2128
|
+
stepFn.retry = (id, operation, options2) => {
|
|
2129
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
2130
|
+
throw new Error(
|
|
2131
|
+
'[awaitly] step.retry() requires an explicit string ID as the first argument. Example: step.retry("fetchData", () => fetchData(), { attempts: 3 })'
|
|
2132
|
+
);
|
|
2133
|
+
}
|
|
2134
|
+
return stepFn(id, operation, {
|
|
2135
|
+
key: options2.key ?? id,
|
|
2136
|
+
retry: {
|
|
2137
|
+
attempts: options2.attempts,
|
|
2138
|
+
backoff: options2.backoff,
|
|
2139
|
+
initialDelay: options2.initialDelay,
|
|
2140
|
+
maxDelay: options2.maxDelay,
|
|
2141
|
+
jitter: options2.jitter,
|
|
2142
|
+
shouldRetry: options2.shouldRetry,
|
|
2143
|
+
onRetry: options2.onRetry
|
|
2144
|
+
},
|
|
2145
|
+
timeout: options2.timeout
|
|
2146
|
+
});
|
|
2147
|
+
};
|
|
2148
|
+
stepFn.withTimeout = (id, operation, options2) => {
|
|
2149
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
2150
|
+
throw new Error(
|
|
2151
|
+
'[awaitly] step.withTimeout() requires an explicit string ID as the first argument. Example: step.withTimeout("slowOp", () => slowOp(), { ms: 5000 })'
|
|
2152
|
+
);
|
|
2153
|
+
}
|
|
2154
|
+
return stepFn(
|
|
2155
|
+
id,
|
|
2156
|
+
operation,
|
|
2157
|
+
{
|
|
2158
|
+
key: options2.key ?? id,
|
|
2159
|
+
timeout: options2
|
|
2160
|
+
}
|
|
2161
|
+
);
|
|
2162
|
+
};
|
|
2163
|
+
stepFn.sleep = (id, duration, options2) => {
|
|
2164
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
2165
|
+
throw new Error(
|
|
2166
|
+
'[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")'
|
|
2167
|
+
);
|
|
2168
|
+
}
|
|
2169
|
+
const d = typeof duration === "string" ? parseDurationString(duration) : duration;
|
|
2170
|
+
if (!d) {
|
|
2171
|
+
throw new Error(`step.sleep: invalid duration '${duration}'`);
|
|
2172
|
+
}
|
|
2173
|
+
const ms = d.millis;
|
|
2174
|
+
const userSignal = options2?.signal;
|
|
2175
|
+
return stepFn(
|
|
2176
|
+
id,
|
|
2177
|
+
async () => {
|
|
2178
|
+
if (_workflowSignal?.aborted || userSignal?.aborted) {
|
|
2179
|
+
const e = new Error("Sleep aborted");
|
|
2180
|
+
e.name = "AbortError";
|
|
2181
|
+
throw e;
|
|
2182
|
+
}
|
|
2183
|
+
return new Promise((resolve, reject) => {
|
|
2184
|
+
const state = { timeoutId: void 0 };
|
|
2185
|
+
const onAbort = () => {
|
|
2186
|
+
if (state.timeoutId) clearTimeout(state.timeoutId);
|
|
2187
|
+
const e = new Error("Sleep aborted");
|
|
2188
|
+
e.name = "AbortError";
|
|
2189
|
+
reject(e);
|
|
2190
|
+
};
|
|
2191
|
+
_workflowSignal?.addEventListener("abort", onAbort, { once: true });
|
|
2192
|
+
userSignal?.addEventListener("abort", onAbort, { once: true });
|
|
2193
|
+
state.timeoutId = setTimeout(() => {
|
|
2194
|
+
_workflowSignal?.removeEventListener("abort", onAbort);
|
|
2195
|
+
userSignal?.removeEventListener("abort", onAbort);
|
|
2196
|
+
resolve(ok2(void 0));
|
|
2197
|
+
}, ms);
|
|
2198
|
+
});
|
|
2199
|
+
},
|
|
2200
|
+
{
|
|
2201
|
+
key: options2?.key ?? id,
|
|
2202
|
+
description: options2?.description
|
|
2203
|
+
}
|
|
2204
|
+
);
|
|
2205
|
+
};
|
|
2206
|
+
stepFn.all = ((...args) => {
|
|
2207
|
+
if (typeof args[0] !== "string") {
|
|
2208
|
+
throw new TypeError(
|
|
2209
|
+
"step.all(name, ...): first argument must be a string (step name). Example: step.all('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })"
|
|
2210
|
+
);
|
|
2211
|
+
}
|
|
2212
|
+
const name = args[0];
|
|
2213
|
+
const second = args[1];
|
|
2214
|
+
if (typeof second === "function") {
|
|
2215
|
+
return executeParallelArray2(name, second);
|
|
2216
|
+
}
|
|
2217
|
+
if (second && typeof second === "object" && !Array.isArray(second)) {
|
|
2218
|
+
const rawOperations = second;
|
|
2219
|
+
const normalizedOperations = normalizeParallelOperations2(rawOperations);
|
|
2220
|
+
return executeParallelNamed2(normalizedOperations, { name });
|
|
2221
|
+
}
|
|
2222
|
+
throw new TypeError(
|
|
2223
|
+
"step.all(name, ...): second argument must be a function (array form) or an object of operations (object form)."
|
|
2224
|
+
);
|
|
2225
|
+
});
|
|
2226
|
+
stepFn.race = (name, operation) => {
|
|
2227
|
+
const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
2228
|
+
return (async () => {
|
|
2229
|
+
const startTime = performance.now();
|
|
2230
|
+
let scopeEnded = false;
|
|
2231
|
+
const scopeEntry = { scopeId, type: "race", winnerId: void 0 };
|
|
2232
|
+
activeScopeStack.push(scopeEntry);
|
|
2233
|
+
const emitScopeEnd = () => {
|
|
2234
|
+
if (scopeEnded) return;
|
|
2235
|
+
scopeEnded = true;
|
|
2236
|
+
const idx = activeScopeStack.findIndex((s) => s.scopeId === scopeId);
|
|
2237
|
+
if (idx !== -1) activeScopeStack.splice(idx, 1);
|
|
2238
|
+
emitEvent({
|
|
2239
|
+
type: "scope_end",
|
|
2240
|
+
workflowId,
|
|
2241
|
+
scopeId,
|
|
2242
|
+
ts: Date.now(),
|
|
2243
|
+
durationMs: performance.now() - startTime,
|
|
2244
|
+
winnerId: scopeEntry.winnerId
|
|
2245
|
+
});
|
|
2246
|
+
};
|
|
2247
|
+
emitEvent({
|
|
2248
|
+
type: "scope_start",
|
|
2249
|
+
workflowId,
|
|
2250
|
+
scopeId,
|
|
2251
|
+
scopeType: "race",
|
|
2252
|
+
name,
|
|
2253
|
+
ts: Date.now()
|
|
2254
|
+
});
|
|
2255
|
+
try {
|
|
2256
|
+
const result = await operation();
|
|
2257
|
+
emitScopeEnd();
|
|
2258
|
+
if (!result.ok) {
|
|
2259
|
+
onError?.(result.error, name, context);
|
|
2260
|
+
throw earlyExit(result.error, {
|
|
2261
|
+
origin: "result",
|
|
2262
|
+
resultCause: result.cause
|
|
2263
|
+
});
|
|
2264
|
+
}
|
|
2265
|
+
return result.value;
|
|
2266
|
+
} catch (error) {
|
|
2267
|
+
emitScopeEnd();
|
|
2268
|
+
throw error;
|
|
2269
|
+
}
|
|
2270
|
+
})();
|
|
2271
|
+
};
|
|
2272
|
+
stepFn.if = (id, conditionLabel, condition) => {
|
|
2273
|
+
assertDeclared(id, "decision");
|
|
2274
|
+
const value2 = condition();
|
|
2275
|
+
emitEvent({
|
|
2276
|
+
type: "decision",
|
|
2277
|
+
workflowId,
|
|
2278
|
+
decisionId: id,
|
|
2279
|
+
label: conditionLabel,
|
|
2280
|
+
branch: value2 ? "then" : "else",
|
|
2281
|
+
value: value2,
|
|
2282
|
+
ts: Date.now()
|
|
2283
|
+
});
|
|
2284
|
+
return value2;
|
|
2285
|
+
};
|
|
2286
|
+
stepFn.label = stepFn.if;
|
|
2287
|
+
stepFn.branch = async (id, options2) => {
|
|
2288
|
+
const { condition, then: thenFn, else: elseFn } = options2;
|
|
2289
|
+
assertDeclared(id, "decision");
|
|
2290
|
+
const conditionResult = condition();
|
|
2291
|
+
const branch = conditionResult ? "then" : "else";
|
|
2292
|
+
const startTime = performance.now();
|
|
2293
|
+
emitEvent({
|
|
2294
|
+
type: "decision",
|
|
2295
|
+
workflowId,
|
|
2296
|
+
decisionId: id,
|
|
2297
|
+
label: options2.conditionLabel,
|
|
2298
|
+
branch,
|
|
2299
|
+
value: conditionResult,
|
|
2300
|
+
phase: "start",
|
|
2301
|
+
ts: Date.now()
|
|
2302
|
+
});
|
|
2303
|
+
const emitEnd = () => {
|
|
2304
|
+
emitEvent({
|
|
2305
|
+
type: "decision",
|
|
2306
|
+
workflowId,
|
|
2307
|
+
decisionId: id,
|
|
2308
|
+
label: options2.conditionLabel,
|
|
2309
|
+
branch,
|
|
2310
|
+
value: conditionResult,
|
|
2311
|
+
phase: "end",
|
|
2312
|
+
durationMs: performance.now() - startTime,
|
|
2313
|
+
ts: Date.now()
|
|
2314
|
+
});
|
|
2315
|
+
};
|
|
2316
|
+
try {
|
|
2317
|
+
if (conditionResult) {
|
|
2318
|
+
return await thenFn();
|
|
2319
|
+
} else if (elseFn) {
|
|
2320
|
+
return await elseFn();
|
|
2321
|
+
}
|
|
2322
|
+
return void 0;
|
|
2323
|
+
} finally {
|
|
2324
|
+
emitEnd();
|
|
2325
|
+
}
|
|
2326
|
+
};
|
|
2327
|
+
stepFn.arm = (fn2, errors) => {
|
|
2328
|
+
return { fn: fn2, errors };
|
|
2329
|
+
};
|
|
2330
|
+
stepFn.forEach = async (_id, items, options2) => {
|
|
2331
|
+
const results = [];
|
|
2332
|
+
const maxIterations = options2.maxIterations;
|
|
2333
|
+
let index = 0;
|
|
2334
|
+
const isRunForm = "run" in options2;
|
|
2335
|
+
const asyncItems = Symbol.asyncIterator in items ? items : (async function* () {
|
|
2336
|
+
yield* items;
|
|
2337
|
+
})();
|
|
2338
|
+
for await (const item of asyncItems) {
|
|
2339
|
+
if (maxIterations !== void 0 && index >= maxIterations) {
|
|
2340
|
+
break;
|
|
2341
|
+
}
|
|
2342
|
+
let result;
|
|
2343
|
+
if (isRunForm) {
|
|
2344
|
+
const runOptions = options2;
|
|
2345
|
+
result = await runOptions.run(item, index);
|
|
2346
|
+
} else {
|
|
2347
|
+
const itemOptions = options2;
|
|
2348
|
+
result = await itemOptions.item.handler(item, index, stepFn);
|
|
2349
|
+
}
|
|
2350
|
+
results.push(result);
|
|
2351
|
+
index++;
|
|
2352
|
+
}
|
|
2353
|
+
return results;
|
|
2354
|
+
};
|
|
2355
|
+
stepFn.item = (handler) => {
|
|
2356
|
+
return {
|
|
2357
|
+
__forEachItemHandler: true,
|
|
2358
|
+
handler
|
|
2359
|
+
};
|
|
2360
|
+
};
|
|
2361
|
+
stepFn.dep = (_name, fn2) => {
|
|
2362
|
+
return fn2;
|
|
2363
|
+
};
|
|
2364
|
+
stepFn.workflow = (id, getter, options2) => {
|
|
2365
|
+
return stepFn(id, getter, options2);
|
|
2366
|
+
};
|
|
2367
|
+
stepFn.map = async (id, items, mapper, options2) => {
|
|
2368
|
+
const concurrency = options2?.concurrency ?? items.length;
|
|
2369
|
+
return stepFn(
|
|
2370
|
+
id,
|
|
2371
|
+
() => {
|
|
2372
|
+
if (concurrency >= items.length) {
|
|
2373
|
+
return allAsync2(items.map((item, index) => mapper(item, index)));
|
|
2374
|
+
} else {
|
|
2375
|
+
return (async () => {
|
|
2376
|
+
const results = [];
|
|
2377
|
+
for (let i = 0; i < items.length; i += concurrency) {
|
|
2378
|
+
const batch = items.slice(i, i + concurrency);
|
|
2379
|
+
const batchResult = await allAsync2(
|
|
2380
|
+
batch.map((item, batchIndex) => mapper(item, i + batchIndex))
|
|
2381
|
+
);
|
|
2382
|
+
if (!batchResult.ok) {
|
|
2383
|
+
return batchResult;
|
|
2384
|
+
}
|
|
2385
|
+
results.push(...batchResult.value);
|
|
2386
|
+
}
|
|
2387
|
+
return ok2(results);
|
|
2388
|
+
})();
|
|
2389
|
+
}
|
|
2390
|
+
},
|
|
2391
|
+
{ key: options2?.key }
|
|
2392
|
+
);
|
|
2393
|
+
};
|
|
2394
|
+
stepFn.withFallback = (id, operation, options2) => {
|
|
2395
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
2396
|
+
throw new Error(
|
|
2397
|
+
'[awaitly] step.withFallback() requires an explicit string ID as the first argument. Example: step.withFallback("getUser", () => fetchUser(id), { fallback: () => fetchFromCache(id) })'
|
|
2398
|
+
);
|
|
2399
|
+
}
|
|
2400
|
+
assertDeclared(id, "step");
|
|
2401
|
+
const stepKey = options2.key ?? id;
|
|
2402
|
+
const stepName = id;
|
|
2403
|
+
const stepId = generateStepId(stepKey);
|
|
2404
|
+
const hasEventListeners = onEvent;
|
|
2405
|
+
return (async () => {
|
|
2406
|
+
const startTime = hasEventListeners ? performance.now() : 0;
|
|
2407
|
+
if (onEvent) {
|
|
2408
|
+
emitEvent({
|
|
2409
|
+
type: "step_start",
|
|
2410
|
+
workflowId,
|
|
2411
|
+
stepId,
|
|
2412
|
+
stepKey,
|
|
2413
|
+
name: stepName,
|
|
2414
|
+
ts: Date.now()
|
|
2415
|
+
});
|
|
2416
|
+
}
|
|
2417
|
+
let primaryResult;
|
|
2418
|
+
try {
|
|
2419
|
+
primaryResult = await operation();
|
|
2420
|
+
} catch (thrown) {
|
|
2421
|
+
if (isEarlyExitE(thrown)) {
|
|
2422
|
+
emitEvent({
|
|
2423
|
+
type: "step_aborted",
|
|
2424
|
+
workflowId,
|
|
2425
|
+
stepId,
|
|
2426
|
+
stepKey,
|
|
2427
|
+
name: stepName,
|
|
2428
|
+
ts: Date.now(),
|
|
2429
|
+
durationMs: performance.now() - startTime
|
|
2430
|
+
});
|
|
2431
|
+
throw thrown;
|
|
2432
|
+
}
|
|
2433
|
+
let mappedError;
|
|
2434
|
+
try {
|
|
2435
|
+
mappedError = effectiveCatchUnexpected(thrown);
|
|
2436
|
+
} catch (mapperError) {
|
|
2437
|
+
throw createMapperException(mapperError);
|
|
2438
|
+
}
|
|
2439
|
+
if (options2.on !== void 0 && options2.on !== mappedError) {
|
|
2440
|
+
const durationMs2 = performance.now() - startTime;
|
|
2441
|
+
emitEvent({
|
|
2442
|
+
type: "step_error",
|
|
2443
|
+
workflowId,
|
|
2444
|
+
stepId,
|
|
2445
|
+
stepKey,
|
|
2446
|
+
name: stepName,
|
|
2447
|
+
ts: Date.now(),
|
|
2448
|
+
durationMs: durationMs2,
|
|
2449
|
+
error: mappedError
|
|
2450
|
+
});
|
|
2451
|
+
if (stepKey) {
|
|
2452
|
+
emitEvent({
|
|
2453
|
+
type: "step_complete",
|
|
2454
|
+
workflowId,
|
|
2455
|
+
stepKey,
|
|
2456
|
+
name: stepName,
|
|
2457
|
+
ts: Date.now(),
|
|
2458
|
+
durationMs: durationMs2,
|
|
2459
|
+
result: err2(mappedError, { cause: thrown }),
|
|
2460
|
+
meta: { origin: "throw", thrown }
|
|
2461
|
+
});
|
|
2462
|
+
}
|
|
2463
|
+
onError?.(mappedError, stepName, context);
|
|
2464
|
+
throw earlyExit(mappedError, { origin: "throw", thrown });
|
|
2465
|
+
}
|
|
2466
|
+
let fallbackResultFromThrow;
|
|
2467
|
+
try {
|
|
2468
|
+
fallbackResultFromThrow = await options2.fallback();
|
|
2469
|
+
} catch (fallbackThrown) {
|
|
2470
|
+
if (isEarlyExitE(fallbackThrown)) {
|
|
2471
|
+
emitEvent({
|
|
2472
|
+
type: "step_aborted",
|
|
2473
|
+
workflowId,
|
|
2474
|
+
stepId,
|
|
2475
|
+
stepKey,
|
|
2476
|
+
name: stepName,
|
|
2477
|
+
ts: Date.now(),
|
|
2478
|
+
durationMs: performance.now() - startTime
|
|
2479
|
+
});
|
|
2480
|
+
throw fallbackThrown;
|
|
2481
|
+
}
|
|
2482
|
+
let fallbackMappedError;
|
|
2483
|
+
try {
|
|
2484
|
+
fallbackMappedError = effectiveCatchUnexpected(fallbackThrown);
|
|
2485
|
+
} catch (mapperError) {
|
|
2486
|
+
throw createMapperException(mapperError);
|
|
2487
|
+
}
|
|
2488
|
+
const durationMs2 = performance.now() - startTime;
|
|
2489
|
+
emitEvent({
|
|
2490
|
+
type: "step_error",
|
|
2491
|
+
workflowId,
|
|
2492
|
+
stepId,
|
|
2493
|
+
stepKey,
|
|
2494
|
+
name: stepName,
|
|
2495
|
+
ts: Date.now(),
|
|
2496
|
+
durationMs: durationMs2,
|
|
2497
|
+
error: fallbackMappedError
|
|
2498
|
+
});
|
|
2499
|
+
if (stepKey) {
|
|
2500
|
+
emitEvent({
|
|
2501
|
+
type: "step_complete",
|
|
2502
|
+
workflowId,
|
|
2503
|
+
stepKey,
|
|
2504
|
+
name: stepName,
|
|
2505
|
+
ts: Date.now(),
|
|
2506
|
+
durationMs: durationMs2,
|
|
2507
|
+
result: err2(fallbackMappedError, { cause: fallbackThrown }),
|
|
2508
|
+
meta: { origin: "throw", thrown: fallbackThrown }
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
onError?.(fallbackMappedError, stepName, context);
|
|
2512
|
+
throw earlyExit(fallbackMappedError, { origin: "throw", thrown: fallbackThrown });
|
|
2513
|
+
}
|
|
2514
|
+
if (fallbackResultFromThrow.ok) {
|
|
2515
|
+
const durationMs2 = performance.now() - startTime;
|
|
2516
|
+
emitEvent({
|
|
2517
|
+
type: "step_success",
|
|
2518
|
+
workflowId,
|
|
2519
|
+
stepId,
|
|
2520
|
+
stepKey,
|
|
2521
|
+
name: stepName,
|
|
2522
|
+
ts: Date.now(),
|
|
2523
|
+
durationMs: durationMs2
|
|
2524
|
+
});
|
|
2525
|
+
if (stepKey) {
|
|
2526
|
+
emitEvent({
|
|
2527
|
+
type: "step_complete",
|
|
2528
|
+
workflowId,
|
|
2529
|
+
stepKey,
|
|
2530
|
+
name: stepName,
|
|
2531
|
+
ts: Date.now(),
|
|
2532
|
+
durationMs: durationMs2,
|
|
2533
|
+
result: fallbackResultFromThrow,
|
|
2534
|
+
meta: { origin: "fallback", fallbackUsed: true, fallbackReason: String(mappedError) }
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
return fallbackResultFromThrow.value;
|
|
2538
|
+
} else {
|
|
2539
|
+
const durationMs2 = performance.now() - startTime;
|
|
2540
|
+
const wrappedError2 = wrapForStep(fallbackResultFromThrow.error, {
|
|
2541
|
+
origin: "result",
|
|
2542
|
+
resultCause: fallbackResultFromThrow.cause
|
|
2543
|
+
});
|
|
2544
|
+
emitEvent({
|
|
2545
|
+
type: "step_error",
|
|
2546
|
+
workflowId,
|
|
2547
|
+
stepId,
|
|
2548
|
+
stepKey,
|
|
2549
|
+
name: stepName,
|
|
2550
|
+
ts: Date.now(),
|
|
2551
|
+
durationMs: durationMs2,
|
|
2552
|
+
error: wrappedError2
|
|
2553
|
+
});
|
|
2554
|
+
if (stepKey) {
|
|
2555
|
+
emitEvent({
|
|
2556
|
+
type: "step_complete",
|
|
2557
|
+
workflowId,
|
|
2558
|
+
stepKey,
|
|
2559
|
+
name: stepName,
|
|
2560
|
+
ts: Date.now(),
|
|
2561
|
+
durationMs: durationMs2,
|
|
2562
|
+
result: fallbackResultFromThrow,
|
|
2563
|
+
meta: { origin: "result", resultCause: fallbackResultFromThrow.cause }
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2566
|
+
onError?.(wrappedError2, stepName, context);
|
|
2567
|
+
throw earlyExit(wrappedError2, {
|
|
2568
|
+
origin: "result",
|
|
2569
|
+
resultCause: fallbackResultFromThrow.cause
|
|
2570
|
+
});
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
if (primaryResult.ok) {
|
|
2574
|
+
const durationMs2 = performance.now() - startTime;
|
|
2575
|
+
emitEvent({
|
|
2576
|
+
type: "step_success",
|
|
2577
|
+
workflowId,
|
|
2578
|
+
stepId,
|
|
2579
|
+
stepKey,
|
|
2580
|
+
name: stepName,
|
|
2581
|
+
ts: Date.now(),
|
|
2582
|
+
durationMs: durationMs2
|
|
2583
|
+
});
|
|
2584
|
+
if (stepKey) {
|
|
2585
|
+
emitEvent({
|
|
2586
|
+
type: "step_complete",
|
|
2587
|
+
workflowId,
|
|
2588
|
+
stepKey,
|
|
2589
|
+
name: stepName,
|
|
2590
|
+
ts: Date.now(),
|
|
2591
|
+
durationMs: durationMs2,
|
|
2592
|
+
result: primaryResult
|
|
2593
|
+
});
|
|
2594
|
+
}
|
|
2595
|
+
return primaryResult.value;
|
|
2596
|
+
}
|
|
2597
|
+
const primaryError = primaryResult.error;
|
|
2598
|
+
if (options2.on !== void 0 && options2.on !== primaryError) {
|
|
2599
|
+
const durationMs2 = performance.now() - startTime;
|
|
2600
|
+
const wrappedError2 = wrapForStep(primaryError, {
|
|
2601
|
+
origin: "result",
|
|
2602
|
+
resultCause: primaryResult.cause
|
|
2603
|
+
});
|
|
2604
|
+
emitEvent({
|
|
2605
|
+
type: "step_error",
|
|
2606
|
+
workflowId,
|
|
2607
|
+
stepId,
|
|
2608
|
+
stepKey,
|
|
2609
|
+
name: stepName,
|
|
2610
|
+
ts: Date.now(),
|
|
2611
|
+
durationMs: durationMs2,
|
|
2612
|
+
error: wrappedError2
|
|
2613
|
+
});
|
|
2614
|
+
if (stepKey) {
|
|
2615
|
+
emitEvent({
|
|
2616
|
+
type: "step_complete",
|
|
2617
|
+
workflowId,
|
|
2618
|
+
stepKey,
|
|
2619
|
+
name: stepName,
|
|
2620
|
+
ts: Date.now(),
|
|
2621
|
+
durationMs: durationMs2,
|
|
2622
|
+
result: primaryResult,
|
|
2623
|
+
meta: { origin: "result", resultCause: primaryResult.cause }
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
onError?.(wrappedError2, stepName, context);
|
|
2627
|
+
throw earlyExit(wrappedError2, {
|
|
2628
|
+
origin: "result",
|
|
2629
|
+
resultCause: primaryResult.cause
|
|
2630
|
+
});
|
|
2631
|
+
}
|
|
2632
|
+
let fallbackResult;
|
|
2633
|
+
try {
|
|
2634
|
+
fallbackResult = await options2.fallback();
|
|
2635
|
+
} catch (thrown) {
|
|
2636
|
+
if (isEarlyExitE(thrown)) {
|
|
2637
|
+
emitEvent({
|
|
2638
|
+
type: "step_aborted",
|
|
2639
|
+
workflowId,
|
|
2640
|
+
stepId,
|
|
2641
|
+
stepKey,
|
|
2642
|
+
name: stepName,
|
|
2643
|
+
ts: Date.now(),
|
|
2644
|
+
durationMs: performance.now() - startTime
|
|
2645
|
+
});
|
|
2646
|
+
throw thrown;
|
|
2647
|
+
}
|
|
2648
|
+
let mappedError;
|
|
2649
|
+
try {
|
|
2650
|
+
mappedError = effectiveCatchUnexpected(thrown);
|
|
2651
|
+
} catch (mapperError) {
|
|
2652
|
+
throw createMapperException(mapperError);
|
|
2653
|
+
}
|
|
2654
|
+
const durationMs2 = performance.now() - startTime;
|
|
2655
|
+
emitEvent({
|
|
2656
|
+
type: "step_error",
|
|
2657
|
+
workflowId,
|
|
2658
|
+
stepId,
|
|
2659
|
+
stepKey,
|
|
2660
|
+
name: stepName,
|
|
2661
|
+
ts: Date.now(),
|
|
2662
|
+
durationMs: durationMs2,
|
|
2663
|
+
error: mappedError
|
|
2664
|
+
});
|
|
2665
|
+
if (stepKey) {
|
|
2666
|
+
emitEvent({
|
|
2667
|
+
type: "step_complete",
|
|
2668
|
+
workflowId,
|
|
2669
|
+
stepKey,
|
|
2670
|
+
name: stepName,
|
|
2671
|
+
ts: Date.now(),
|
|
2672
|
+
durationMs: durationMs2,
|
|
2673
|
+
result: err2(mappedError, { cause: thrown }),
|
|
2674
|
+
meta: { origin: "throw", thrown }
|
|
2675
|
+
});
|
|
2676
|
+
}
|
|
2677
|
+
onError?.(mappedError, stepName, context);
|
|
2678
|
+
throw earlyExit(mappedError, { origin: "throw", thrown });
|
|
2679
|
+
}
|
|
2680
|
+
if (fallbackResult.ok) {
|
|
2681
|
+
const durationMs2 = performance.now() - startTime;
|
|
2682
|
+
emitEvent({
|
|
2683
|
+
type: "step_success",
|
|
2684
|
+
workflowId,
|
|
2685
|
+
stepId,
|
|
2686
|
+
stepKey,
|
|
2687
|
+
name: stepName,
|
|
2688
|
+
ts: Date.now(),
|
|
2689
|
+
durationMs: durationMs2
|
|
2690
|
+
});
|
|
2691
|
+
if (stepKey) {
|
|
2692
|
+
emitEvent({
|
|
2693
|
+
type: "step_complete",
|
|
2694
|
+
workflowId,
|
|
2695
|
+
stepKey,
|
|
2696
|
+
name: stepName,
|
|
2697
|
+
ts: Date.now(),
|
|
2698
|
+
durationMs: durationMs2,
|
|
2699
|
+
result: fallbackResult,
|
|
2700
|
+
meta: { origin: "fallback", fallbackUsed: true, fallbackReason: String(primaryError) }
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2703
|
+
return fallbackResult.value;
|
|
2704
|
+
}
|
|
2705
|
+
const durationMs = performance.now() - startTime;
|
|
2706
|
+
const wrappedError = wrapForStep(fallbackResult.error, {
|
|
2707
|
+
origin: "result",
|
|
2708
|
+
resultCause: fallbackResult.cause
|
|
2709
|
+
});
|
|
2710
|
+
emitEvent({
|
|
2711
|
+
type: "step_error",
|
|
2712
|
+
workflowId,
|
|
2713
|
+
stepId,
|
|
2714
|
+
stepKey,
|
|
2715
|
+
name: stepName,
|
|
2716
|
+
ts: Date.now(),
|
|
2717
|
+
durationMs,
|
|
2718
|
+
error: wrappedError
|
|
2719
|
+
});
|
|
2720
|
+
if (stepKey) {
|
|
2721
|
+
emitEvent({
|
|
2722
|
+
type: "step_complete",
|
|
2723
|
+
workflowId,
|
|
2724
|
+
stepKey,
|
|
2725
|
+
name: stepName,
|
|
2726
|
+
ts: Date.now(),
|
|
2727
|
+
durationMs,
|
|
2728
|
+
result: fallbackResult,
|
|
2729
|
+
meta: { origin: "result", resultCause: fallbackResult.cause }
|
|
2730
|
+
});
|
|
2731
|
+
}
|
|
2732
|
+
onError?.(wrappedError, stepName, context);
|
|
2733
|
+
throw earlyExit(wrappedError, {
|
|
2734
|
+
origin: "result",
|
|
2735
|
+
resultCause: fallbackResult.cause
|
|
2736
|
+
});
|
|
2737
|
+
})();
|
|
2738
|
+
};
|
|
2739
|
+
stepFn.withResource = (id, options2) => {
|
|
2740
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
2741
|
+
throw new Error(
|
|
2742
|
+
'[awaitly] step.withResource() requires an explicit string ID as the first argument. Example: step.withResource("useDb", { acquire: () => connect(), use: (db) => query(db), release: (db) => db.close() })'
|
|
2743
|
+
);
|
|
2744
|
+
}
|
|
2745
|
+
assertDeclared(id, "step");
|
|
2746
|
+
const stepKey = id;
|
|
2747
|
+
const stepName = id;
|
|
2748
|
+
const stepId = generateStepId(stepKey);
|
|
2749
|
+
const hasEventListeners = onEvent;
|
|
2750
|
+
return (async () => {
|
|
2751
|
+
const startTime = hasEventListeners ? performance.now() : 0;
|
|
2752
|
+
if (onEvent) {
|
|
2753
|
+
emitEvent({
|
|
2754
|
+
type: "step_start",
|
|
2755
|
+
workflowId,
|
|
2756
|
+
stepId,
|
|
2757
|
+
stepKey,
|
|
2758
|
+
name: stepName,
|
|
2759
|
+
ts: Date.now()
|
|
2760
|
+
});
|
|
2761
|
+
}
|
|
2762
|
+
let acquireResult;
|
|
2763
|
+
try {
|
|
2764
|
+
acquireResult = await options2.acquire();
|
|
2765
|
+
} catch (thrown) {
|
|
2766
|
+
if (isEarlyExitE(thrown)) {
|
|
2767
|
+
emitEvent({
|
|
2768
|
+
type: "step_aborted",
|
|
2769
|
+
workflowId,
|
|
2770
|
+
stepId,
|
|
2771
|
+
stepKey,
|
|
2772
|
+
name: stepName,
|
|
2773
|
+
ts: Date.now(),
|
|
2774
|
+
durationMs: performance.now() - startTime
|
|
2775
|
+
});
|
|
2776
|
+
throw thrown;
|
|
2777
|
+
}
|
|
2778
|
+
let mappedError;
|
|
2779
|
+
try {
|
|
2780
|
+
mappedError = effectiveCatchUnexpected(thrown);
|
|
2781
|
+
} catch (mapperError) {
|
|
2782
|
+
throw createMapperException(mapperError);
|
|
2783
|
+
}
|
|
2784
|
+
const durationMs2 = performance.now() - startTime;
|
|
2785
|
+
emitEvent({
|
|
2786
|
+
type: "step_error",
|
|
2787
|
+
workflowId,
|
|
2788
|
+
stepId,
|
|
2789
|
+
stepKey,
|
|
2790
|
+
name: stepName,
|
|
2791
|
+
ts: Date.now(),
|
|
2792
|
+
durationMs: durationMs2,
|
|
2793
|
+
error: mappedError
|
|
2794
|
+
});
|
|
2795
|
+
if (stepKey) {
|
|
2796
|
+
emitEvent({
|
|
2797
|
+
type: "step_complete",
|
|
2798
|
+
workflowId,
|
|
2799
|
+
stepKey,
|
|
2800
|
+
name: stepName,
|
|
2801
|
+
ts: Date.now(),
|
|
2802
|
+
durationMs: durationMs2,
|
|
2803
|
+
result: err2(mappedError, { cause: thrown }),
|
|
2804
|
+
meta: { origin: "throw", thrown }
|
|
2805
|
+
});
|
|
2806
|
+
}
|
|
2807
|
+
onError?.(mappedError, stepName, context);
|
|
2808
|
+
throw earlyExit(mappedError, { origin: "throw", thrown });
|
|
2809
|
+
}
|
|
2810
|
+
if (!acquireResult.ok) {
|
|
2811
|
+
const durationMs2 = performance.now() - startTime;
|
|
2812
|
+
const wrappedError2 = wrapForStep(acquireResult.error, {
|
|
2813
|
+
origin: "result",
|
|
2814
|
+
resultCause: acquireResult.cause
|
|
2815
|
+
});
|
|
2816
|
+
emitEvent({
|
|
2817
|
+
type: "step_error",
|
|
2818
|
+
workflowId,
|
|
2819
|
+
stepId,
|
|
2820
|
+
stepKey,
|
|
2821
|
+
name: stepName,
|
|
2822
|
+
ts: Date.now(),
|
|
2823
|
+
durationMs: durationMs2,
|
|
2824
|
+
error: wrappedError2
|
|
2825
|
+
});
|
|
2826
|
+
if (stepKey) {
|
|
2827
|
+
emitEvent({
|
|
2828
|
+
type: "step_complete",
|
|
2829
|
+
workflowId,
|
|
2830
|
+
stepKey,
|
|
2831
|
+
name: stepName,
|
|
2832
|
+
ts: Date.now(),
|
|
2833
|
+
durationMs: durationMs2,
|
|
2834
|
+
result: acquireResult,
|
|
2835
|
+
meta: { origin: "result", resultCause: acquireResult.cause }
|
|
2836
|
+
});
|
|
2837
|
+
}
|
|
2838
|
+
onError?.(wrappedError2, stepName, context);
|
|
2839
|
+
throw earlyExit(wrappedError2, {
|
|
2840
|
+
origin: "result",
|
|
2841
|
+
resultCause: acquireResult.cause
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2844
|
+
const resource = acquireResult.value;
|
|
2845
|
+
let useResult;
|
|
2846
|
+
let useThrown;
|
|
2847
|
+
let useThrewNonResult = false;
|
|
2848
|
+
try {
|
|
2849
|
+
useResult = await options2.use(resource);
|
|
2850
|
+
} catch (thrown) {
|
|
2851
|
+
if (isEarlyExitE(thrown)) {
|
|
2852
|
+
try {
|
|
2853
|
+
await options2.release(resource);
|
|
2854
|
+
} catch (releaseErr) {
|
|
2855
|
+
console.warn(
|
|
2856
|
+
`[awaitly] step.withResource("${id}"): release threw after earlyExit:`,
|
|
2857
|
+
releaseErr
|
|
2858
|
+
);
|
|
2859
|
+
}
|
|
2860
|
+
throw thrown;
|
|
2861
|
+
}
|
|
2862
|
+
useThrown = thrown;
|
|
2863
|
+
useThrewNonResult = true;
|
|
2864
|
+
}
|
|
2865
|
+
try {
|
|
2866
|
+
await options2.release(resource);
|
|
2867
|
+
} catch (releaseErr) {
|
|
2868
|
+
console.warn(
|
|
2869
|
+
`[awaitly] step.withResource("${id}"): release threw:`,
|
|
2870
|
+
releaseErr
|
|
2871
|
+
);
|
|
2872
|
+
}
|
|
2873
|
+
if (useThrewNonResult) {
|
|
2874
|
+
let mappedError;
|
|
2875
|
+
try {
|
|
2876
|
+
mappedError = effectiveCatchUnexpected(useThrown);
|
|
2877
|
+
} catch (mapperError) {
|
|
2878
|
+
throw createMapperException(mapperError);
|
|
2879
|
+
}
|
|
2880
|
+
const durationMs2 = performance.now() - startTime;
|
|
2881
|
+
emitEvent({
|
|
2882
|
+
type: "step_error",
|
|
2883
|
+
workflowId,
|
|
2884
|
+
stepId,
|
|
2885
|
+
stepKey,
|
|
2886
|
+
name: stepName,
|
|
2887
|
+
ts: Date.now(),
|
|
2888
|
+
durationMs: durationMs2,
|
|
2889
|
+
error: mappedError
|
|
2890
|
+
});
|
|
2891
|
+
if (stepKey) {
|
|
2892
|
+
emitEvent({
|
|
2893
|
+
type: "step_complete",
|
|
2894
|
+
workflowId,
|
|
2895
|
+
stepKey,
|
|
2896
|
+
name: stepName,
|
|
2897
|
+
ts: Date.now(),
|
|
2898
|
+
durationMs: durationMs2,
|
|
2899
|
+
result: err2(mappedError, { cause: useThrown }),
|
|
2900
|
+
meta: { origin: "throw", thrown: useThrown }
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
onError?.(mappedError, stepName, context);
|
|
2904
|
+
throw earlyExit(mappedError, { origin: "throw", thrown: useThrown });
|
|
2905
|
+
}
|
|
2906
|
+
const result = useResult;
|
|
2907
|
+
if (result.ok) {
|
|
2908
|
+
const durationMs2 = performance.now() - startTime;
|
|
2909
|
+
emitEvent({
|
|
2910
|
+
type: "step_success",
|
|
2911
|
+
workflowId,
|
|
2912
|
+
stepId,
|
|
2913
|
+
stepKey,
|
|
2914
|
+
name: stepName,
|
|
2915
|
+
ts: Date.now(),
|
|
2916
|
+
durationMs: durationMs2
|
|
2917
|
+
});
|
|
2918
|
+
if (stepKey) {
|
|
2919
|
+
emitEvent({
|
|
2920
|
+
type: "step_complete",
|
|
2921
|
+
workflowId,
|
|
2922
|
+
stepKey,
|
|
2923
|
+
name: stepName,
|
|
2924
|
+
ts: Date.now(),
|
|
2925
|
+
durationMs: durationMs2,
|
|
2926
|
+
result
|
|
2927
|
+
});
|
|
2928
|
+
}
|
|
2929
|
+
return result.value;
|
|
2930
|
+
}
|
|
2931
|
+
const durationMs = performance.now() - startTime;
|
|
2932
|
+
const wrappedError = wrapForStep(result.error, {
|
|
2933
|
+
origin: "result",
|
|
2934
|
+
resultCause: result.cause
|
|
2935
|
+
});
|
|
2936
|
+
emitEvent({
|
|
2937
|
+
type: "step_error",
|
|
2938
|
+
workflowId,
|
|
2939
|
+
stepId,
|
|
2940
|
+
stepKey,
|
|
2941
|
+
name: stepName,
|
|
2942
|
+
ts: Date.now(),
|
|
2943
|
+
durationMs,
|
|
2944
|
+
error: wrappedError
|
|
2945
|
+
});
|
|
2946
|
+
if (stepKey) {
|
|
2947
|
+
emitEvent({
|
|
2948
|
+
type: "step_complete",
|
|
2949
|
+
workflowId,
|
|
2950
|
+
stepKey,
|
|
2951
|
+
name: stepName,
|
|
2952
|
+
ts: Date.now(),
|
|
2953
|
+
durationMs,
|
|
2954
|
+
result,
|
|
2955
|
+
meta: { origin: "result", resultCause: result.cause }
|
|
2956
|
+
});
|
|
2957
|
+
}
|
|
2958
|
+
onError?.(wrappedError, stepName, context);
|
|
2959
|
+
throw earlyExit(wrappedError, {
|
|
2960
|
+
origin: "result",
|
|
2961
|
+
resultCause: result.cause
|
|
2962
|
+
});
|
|
2963
|
+
})();
|
|
2964
|
+
};
|
|
2965
|
+
const step = stepFn;
|
|
2966
|
+
const value = await fn({ step });
|
|
2967
|
+
if (process.env.NODE_ENV !== "production" && value !== null && typeof value === "object" && "ok" in value && typeof value.ok === "boolean") {
|
|
2968
|
+
const maybeResult = value;
|
|
2969
|
+
if (maybeResult.ok === true && "value" in maybeResult || maybeResult.ok === false && "error" in maybeResult) {
|
|
2970
|
+
console.warn(
|
|
2971
|
+
`awaitly: Workflow executor returned a Result-like object. Return raw values, not ok() or err().
|
|
2972
|
+
|
|
2973
|
+
Incorrect: return ok({ data });
|
|
2974
|
+
Correct: return { data };
|
|
2975
|
+
|
|
2976
|
+
See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`
|
|
2977
|
+
);
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
return ok2(value);
|
|
2981
|
+
} catch (error) {
|
|
2982
|
+
if (isMapperException(error)) {
|
|
2983
|
+
throw error.thrown;
|
|
2984
|
+
}
|
|
2985
|
+
if (isEarlyExitE(error)) {
|
|
2986
|
+
const originalCause = error.meta.origin === "throw" ? error.meta.thrown : error.meta.origin === "result" ? error.meta.resultCause : void 0;
|
|
2987
|
+
return err2(error.error, { cause: originalCause });
|
|
2988
|
+
}
|
|
2989
|
+
const mapped = effectiveCatchUnexpected(error);
|
|
2990
|
+
onError?.(mapped, "unexpected", context);
|
|
2991
|
+
return err2(mapped, { cause: error });
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
var runStrict = (fn, options) => {
|
|
2995
|
+
return runFn(fn, options);
|
|
2996
|
+
};
|
|
2997
|
+
var run = /* @__PURE__ */ Object.assign(runFn, { strict: runStrict });
|
|
2998
|
+
async function allAsync2(results) {
|
|
2999
|
+
if (results.length === 0) {
|
|
3000
|
+
return ok2([]);
|
|
3001
|
+
}
|
|
3002
|
+
return new Promise((resolve) => {
|
|
3003
|
+
let settled = false;
|
|
3004
|
+
let pendingCount = results.length;
|
|
3005
|
+
const values = new Array(results.length);
|
|
3006
|
+
for (let i = 0; i < results.length; i++) {
|
|
3007
|
+
const index = i;
|
|
3008
|
+
Promise.resolve(results[index]).catch((reason) => err2(
|
|
3009
|
+
{ type: "PROMISE_REJECTED", cause: reason },
|
|
3010
|
+
{ cause: { type: "PROMISE_REJECTION", reason } }
|
|
3011
|
+
)).then((result) => {
|
|
3012
|
+
if (settled) return;
|
|
3013
|
+
if (!result.ok) {
|
|
3014
|
+
settled = true;
|
|
3015
|
+
resolve(result);
|
|
3016
|
+
return;
|
|
3017
|
+
}
|
|
3018
|
+
values[index] = result.value;
|
|
3019
|
+
pendingCount--;
|
|
3020
|
+
if (pendingCount === 0) {
|
|
3021
|
+
resolve(ok2(values));
|
|
3022
|
+
}
|
|
3023
|
+
});
|
|
3024
|
+
}
|
|
3025
|
+
});
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
// src/match.ts
|
|
3029
|
+
function tag(tagValue, handler) {
|
|
3030
|
+
return (matcher) => {
|
|
3031
|
+
const newHandlers = new Map(matcher.handlers);
|
|
3032
|
+
newHandlers.set(tagValue, handler);
|
|
3033
|
+
return {
|
|
3034
|
+
_tag: "Matcher",
|
|
3035
|
+
value: matcher.value,
|
|
3036
|
+
handlers: newHandlers,
|
|
3037
|
+
_remaining: void 0,
|
|
3038
|
+
_output: void 0
|
|
3039
|
+
};
|
|
3040
|
+
};
|
|
3041
|
+
}
|
|
3042
|
+
function tags2(handlers) {
|
|
3043
|
+
return (matcher) => {
|
|
3044
|
+
const newHandlers = new Map(matcher.handlers);
|
|
3045
|
+
for (const [tagValue, handler] of Object.entries(handlers)) {
|
|
3046
|
+
if (handler) {
|
|
3047
|
+
newHandlers.set(tagValue, handler);
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
return {
|
|
3051
|
+
_tag: "Matcher",
|
|
3052
|
+
value: matcher.value,
|
|
3053
|
+
handlers: newHandlers,
|
|
3054
|
+
_remaining: void 0,
|
|
3055
|
+
_output: void 0
|
|
3056
|
+
};
|
|
3057
|
+
};
|
|
3058
|
+
}
|
|
3059
|
+
function exhaustive(matcher) {
|
|
3060
|
+
const handler = matcher.handlers.get(matcher.value._tag);
|
|
3061
|
+
if (!handler) {
|
|
3062
|
+
throw new Error(`No handler for tag: ${matcher.value._tag}`);
|
|
3063
|
+
}
|
|
3064
|
+
return handler(matcher.value);
|
|
3065
|
+
}
|
|
3066
|
+
function orElse2(handler) {
|
|
3067
|
+
return (matcher) => {
|
|
3068
|
+
const specificHandler = matcher.handlers.get(matcher.value._tag);
|
|
3069
|
+
if (specificHandler) {
|
|
3070
|
+
return specificHandler(matcher.value);
|
|
3071
|
+
}
|
|
3072
|
+
return handler(matcher.value);
|
|
3073
|
+
};
|
|
3074
|
+
}
|
|
3075
|
+
function orElseValue(defaultValue) {
|
|
3076
|
+
return orElse2(() => defaultValue);
|
|
3077
|
+
}
|
|
3078
|
+
function when(tagValue, predicate, handler) {
|
|
3079
|
+
return (matcher) => {
|
|
3080
|
+
const newHandlers = new Map(matcher.handlers);
|
|
3081
|
+
const existingHandler = matcher.handlers.get(tagValue);
|
|
3082
|
+
newHandlers.set(tagValue, (value) => {
|
|
3083
|
+
const typedValue = value;
|
|
3084
|
+
if (predicate(typedValue)) {
|
|
3085
|
+
return handler(typedValue);
|
|
3086
|
+
}
|
|
3087
|
+
if (existingHandler) {
|
|
3088
|
+
return existingHandler(value);
|
|
3089
|
+
}
|
|
3090
|
+
throw new Error(`No handler matched for tag: ${tagValue}`);
|
|
3091
|
+
});
|
|
3092
|
+
return {
|
|
3093
|
+
_tag: "Matcher",
|
|
3094
|
+
value: matcher.value,
|
|
3095
|
+
handlers: newHandlers,
|
|
3096
|
+
_remaining: matcher._remaining,
|
|
3097
|
+
_output: void 0
|
|
3098
|
+
};
|
|
3099
|
+
};
|
|
3100
|
+
}
|
|
3101
|
+
function is(tagValue) {
|
|
3102
|
+
return (value) => value._tag === tagValue;
|
|
3103
|
+
}
|
|
3104
|
+
function isOneOf(...tags3) {
|
|
3105
|
+
const tagSet = new Set(tags3);
|
|
3106
|
+
return (value) => tagSet.has(value._tag);
|
|
3107
|
+
}
|
|
3108
|
+
function isMatcher(value) {
|
|
3109
|
+
return typeof value === "object" && value !== null && "_tag" in value && value._tag === "Matcher";
|
|
3110
|
+
}
|
|
3111
|
+
function addPipe(matcher) {
|
|
3112
|
+
return {
|
|
3113
|
+
...matcher,
|
|
3114
|
+
pipe(fn) {
|
|
3115
|
+
const result = fn(matcher);
|
|
3116
|
+
if (isMatcher(result)) {
|
|
3117
|
+
return addPipe(result);
|
|
3118
|
+
}
|
|
3119
|
+
return result;
|
|
3120
|
+
}
|
|
3121
|
+
};
|
|
3122
|
+
}
|
|
3123
|
+
function matchValue(input) {
|
|
3124
|
+
const matcher = {
|
|
3125
|
+
_tag: "Matcher",
|
|
3126
|
+
value: input,
|
|
3127
|
+
handlers: /* @__PURE__ */ new Map(),
|
|
3128
|
+
_remaining: input,
|
|
3129
|
+
_output: void 0
|
|
3130
|
+
};
|
|
3131
|
+
return addPipe(matcher);
|
|
3132
|
+
}
|
|
3133
|
+
var Match = {
|
|
3134
|
+
value: matchValue,
|
|
3135
|
+
tag,
|
|
3136
|
+
tags: tags2,
|
|
3137
|
+
when,
|
|
3138
|
+
exhaustive,
|
|
3139
|
+
orElse: orElse2,
|
|
3140
|
+
orElseValue,
|
|
3141
|
+
is,
|
|
3142
|
+
isOneOf
|
|
3143
|
+
};
|
|
3144
|
+
|
|
3145
|
+
// src/circuit-breaker.ts
|
|
3146
|
+
var CircuitOpenError = class extends Error {
|
|
3147
|
+
type = "CIRCUIT_OPEN";
|
|
3148
|
+
circuitName;
|
|
3149
|
+
state;
|
|
3150
|
+
retryAfterMs;
|
|
3151
|
+
constructor(options) {
|
|
3152
|
+
super(
|
|
3153
|
+
options.message ?? `Circuit breaker "${options.circuitName}" is ${options.state}. Retry after ${Math.ceil(options.retryAfterMs / 1e3)}s`
|
|
3154
|
+
);
|
|
3155
|
+
this.name = "CircuitOpenError";
|
|
3156
|
+
this.circuitName = options.circuitName;
|
|
3157
|
+
this.state = options.state;
|
|
3158
|
+
this.retryAfterMs = options.retryAfterMs;
|
|
3159
|
+
}
|
|
3160
|
+
};
|
|
3161
|
+
function isCircuitOpenError(error) {
|
|
3162
|
+
return typeof error === "object" && error !== null && error.type === "CIRCUIT_OPEN";
|
|
3163
|
+
}
|
|
3164
|
+
var DEFAULT_CONFIG = {
|
|
3165
|
+
failureThreshold: 5,
|
|
3166
|
+
resetTimeout: 3e4,
|
|
3167
|
+
windowSize: 6e4,
|
|
3168
|
+
halfOpenMax: 3
|
|
3169
|
+
};
|
|
3170
|
+
function createCircuitBreaker(name, config) {
|
|
3171
|
+
const effectiveConfig = {
|
|
3172
|
+
...DEFAULT_CONFIG,
|
|
3173
|
+
...config
|
|
3174
|
+
};
|
|
3175
|
+
let state = "CLOSED";
|
|
3176
|
+
let failures = [];
|
|
3177
|
+
let lastFailureTime = null;
|
|
3178
|
+
let lastSuccessTime = null;
|
|
3179
|
+
let successCount = 0;
|
|
3180
|
+
let halfOpenSuccesses = 0;
|
|
3181
|
+
function cleanupFailures() {
|
|
3182
|
+
const now = Date.now();
|
|
3183
|
+
failures = failures.filter(
|
|
3184
|
+
(f) => now - f.timestamp < effectiveConfig.windowSize
|
|
3185
|
+
);
|
|
3186
|
+
}
|
|
3187
|
+
function transitionTo(newState) {
|
|
3188
|
+
if (state !== newState) {
|
|
3189
|
+
const oldState = state;
|
|
3190
|
+
state = newState;
|
|
3191
|
+
if (newState === "HALF_OPEN") {
|
|
3192
|
+
halfOpenSuccesses = 0;
|
|
3193
|
+
}
|
|
3194
|
+
effectiveConfig.onStateChange?.(oldState, newState, name);
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
function checkOpenToHalfOpen() {
|
|
3198
|
+
if (state !== "OPEN" || lastFailureTime === null) {
|
|
3199
|
+
return false;
|
|
3200
|
+
}
|
|
3201
|
+
const now = Date.now();
|
|
3202
|
+
if (now - lastFailureTime >= effectiveConfig.resetTimeout) {
|
|
3203
|
+
transitionTo("HALF_OPEN");
|
|
3204
|
+
return true;
|
|
3205
|
+
}
|
|
3206
|
+
return false;
|
|
3207
|
+
}
|
|
3208
|
+
function handleSuccess() {
|
|
3209
|
+
lastSuccessTime = Date.now();
|
|
3210
|
+
successCount++;
|
|
3211
|
+
if (state === "HALF_OPEN") {
|
|
3212
|
+
halfOpenSuccesses++;
|
|
3213
|
+
if (halfOpenSuccesses >= effectiveConfig.halfOpenMax) {
|
|
3214
|
+
transitionTo("CLOSED");
|
|
3215
|
+
failures = [];
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
function handleFailure(error) {
|
|
3220
|
+
const now = Date.now();
|
|
3221
|
+
lastFailureTime = now;
|
|
3222
|
+
cleanupFailures();
|
|
3223
|
+
failures.push({ timestamp: now, error });
|
|
3224
|
+
if (state === "HALF_OPEN") {
|
|
3225
|
+
transitionTo("OPEN");
|
|
3226
|
+
} else if (state === "CLOSED") {
|
|
3227
|
+
if (failures.length >= effectiveConfig.failureThreshold) {
|
|
3228
|
+
transitionTo("OPEN");
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
function canExecute() {
|
|
3233
|
+
if (state === "CLOSED") {
|
|
3234
|
+
return 0;
|
|
3235
|
+
}
|
|
3236
|
+
if (state === "OPEN") {
|
|
3237
|
+
if (checkOpenToHalfOpen()) {
|
|
3238
|
+
return 0;
|
|
3239
|
+
}
|
|
3240
|
+
const now = Date.now();
|
|
3241
|
+
const elapsed = lastFailureTime ? now - lastFailureTime : 0;
|
|
3242
|
+
return Math.max(0, effectiveConfig.resetTimeout - elapsed);
|
|
3243
|
+
}
|
|
3244
|
+
return 0;
|
|
3245
|
+
}
|
|
3246
|
+
return {
|
|
3247
|
+
async execute(operation, _options) {
|
|
3248
|
+
const waitTime = canExecute();
|
|
3249
|
+
if (waitTime > 0) {
|
|
3250
|
+
throw new CircuitOpenError({
|
|
3251
|
+
circuitName: name,
|
|
3252
|
+
state,
|
|
3253
|
+
retryAfterMs: waitTime
|
|
3254
|
+
});
|
|
3255
|
+
}
|
|
3256
|
+
try {
|
|
3257
|
+
const result = await operation();
|
|
3258
|
+
handleSuccess();
|
|
3259
|
+
return result;
|
|
3260
|
+
} catch (error) {
|
|
3261
|
+
handleFailure(error);
|
|
3262
|
+
throw error;
|
|
3263
|
+
}
|
|
3264
|
+
},
|
|
3265
|
+
async executeResult(operation, _options) {
|
|
3266
|
+
const waitTime = canExecute();
|
|
3267
|
+
if (waitTime > 0) {
|
|
3268
|
+
return err2(
|
|
3269
|
+
new CircuitOpenError({
|
|
3270
|
+
circuitName: name,
|
|
3271
|
+
state,
|
|
3272
|
+
retryAfterMs: waitTime
|
|
3273
|
+
})
|
|
3274
|
+
);
|
|
3275
|
+
}
|
|
3276
|
+
try {
|
|
3277
|
+
const result = await operation();
|
|
3278
|
+
if (result.ok) {
|
|
3279
|
+
handleSuccess();
|
|
3280
|
+
} else {
|
|
3281
|
+
handleFailure(result.error);
|
|
3282
|
+
}
|
|
3283
|
+
return result;
|
|
3284
|
+
} catch (error) {
|
|
3285
|
+
handleFailure(error);
|
|
3286
|
+
throw error;
|
|
3287
|
+
}
|
|
3288
|
+
},
|
|
3289
|
+
getState() {
|
|
3290
|
+
if (state === "OPEN") {
|
|
3291
|
+
checkOpenToHalfOpen();
|
|
3292
|
+
}
|
|
3293
|
+
return state;
|
|
3294
|
+
},
|
|
3295
|
+
getStats() {
|
|
3296
|
+
cleanupFailures();
|
|
3297
|
+
return {
|
|
3298
|
+
state: this.getState(),
|
|
3299
|
+
failureCount: failures.length,
|
|
3300
|
+
successCount,
|
|
3301
|
+
lastFailureTime,
|
|
3302
|
+
lastSuccessTime,
|
|
3303
|
+
halfOpenSuccesses
|
|
3304
|
+
};
|
|
3305
|
+
},
|
|
3306
|
+
reset() {
|
|
3307
|
+
transitionTo("CLOSED");
|
|
3308
|
+
failures = [];
|
|
3309
|
+
halfOpenSuccesses = 0;
|
|
3310
|
+
},
|
|
3311
|
+
forceOpen() {
|
|
3312
|
+
lastFailureTime = Date.now();
|
|
3313
|
+
transitionTo("OPEN");
|
|
3314
|
+
},
|
|
3315
|
+
recordSuccess() {
|
|
3316
|
+
handleSuccess();
|
|
3317
|
+
},
|
|
3318
|
+
recordFailure(error) {
|
|
3319
|
+
handleFailure(error ?? new Error("Manual failure"));
|
|
3320
|
+
}
|
|
3321
|
+
};
|
|
3322
|
+
}
|
|
3323
|
+
var circuitBreakerPresets = {
|
|
3324
|
+
/**
|
|
3325
|
+
* Aggressive circuit breaker for critical paths.
|
|
3326
|
+
* Opens quickly (3 failures) and recovers slowly (60s).
|
|
3327
|
+
*/
|
|
3328
|
+
critical: {
|
|
3329
|
+
failureThreshold: 3,
|
|
3330
|
+
resetTimeout: 6e4,
|
|
3331
|
+
windowSize: 3e4,
|
|
3332
|
+
halfOpenMax: 1
|
|
3333
|
+
},
|
|
3334
|
+
/**
|
|
3335
|
+
* Standard circuit breaker for typical API calls.
|
|
3336
|
+
* Balanced between stability and availability.
|
|
3337
|
+
*/
|
|
3338
|
+
standard: {
|
|
3339
|
+
failureThreshold: 5,
|
|
3340
|
+
resetTimeout: 3e4,
|
|
3341
|
+
windowSize: 6e4,
|
|
3342
|
+
halfOpenMax: 3
|
|
3343
|
+
},
|
|
3344
|
+
/**
|
|
3345
|
+
* Lenient circuit breaker for non-critical operations.
|
|
3346
|
+
* Opens slowly (10 failures) and recovers quickly (15s).
|
|
3347
|
+
*/
|
|
3348
|
+
lenient: {
|
|
3349
|
+
failureThreshold: 10,
|
|
3350
|
+
resetTimeout: 15e3,
|
|
3351
|
+
windowSize: 12e4,
|
|
3352
|
+
halfOpenMax: 5
|
|
3353
|
+
}
|
|
3354
|
+
};
|
|
3355
|
+
|
|
3356
|
+
// src/rate-limiter/index.ts
|
|
3357
|
+
function isRateLimitExceededError(error) {
|
|
3358
|
+
return typeof error === "object" && error !== null && error.type === "RATE_LIMIT_EXCEEDED";
|
|
3359
|
+
}
|
|
3360
|
+
function isQueueFullError(error) {
|
|
3361
|
+
return typeof error === "object" && error !== null && error.type === "QUEUE_FULL";
|
|
3362
|
+
}
|
|
3363
|
+
function createRateLimiter(name, config) {
|
|
3364
|
+
const { maxPerSecond, strategy = "wait" } = config;
|
|
3365
|
+
const maxTokens = config.burstCapacity ?? maxPerSecond * 2;
|
|
3366
|
+
let tokens = maxTokens;
|
|
3367
|
+
let lastRefill = Date.now();
|
|
3368
|
+
const refillRate = maxPerSecond / 1e3;
|
|
3369
|
+
const waitQueue = [];
|
|
3370
|
+
function refill() {
|
|
3371
|
+
const now = Date.now();
|
|
3372
|
+
const elapsed = now - lastRefill;
|
|
3373
|
+
const tokensToAdd = elapsed * refillRate;
|
|
3374
|
+
tokens = Math.min(maxTokens, tokens + tokensToAdd);
|
|
3375
|
+
lastRefill = now;
|
|
3376
|
+
}
|
|
3377
|
+
function tryConsume() {
|
|
3378
|
+
refill();
|
|
3379
|
+
if (tokens >= 1) {
|
|
3380
|
+
tokens -= 1;
|
|
3381
|
+
return 0;
|
|
3382
|
+
}
|
|
3383
|
+
const tokensNeeded = 1 - tokens;
|
|
3384
|
+
return Math.ceil(tokensNeeded / refillRate);
|
|
3385
|
+
}
|
|
3386
|
+
async function waitForToken() {
|
|
3387
|
+
return new Promise((resolve) => {
|
|
3388
|
+
const check = () => {
|
|
3389
|
+
const waitTime = tryConsume();
|
|
3390
|
+
if (waitTime === 0) {
|
|
3391
|
+
resolve();
|
|
3392
|
+
} else {
|
|
3393
|
+
waitQueue.push(check);
|
|
3394
|
+
setTimeout(() => {
|
|
3395
|
+
const idx = waitQueue.indexOf(check);
|
|
3396
|
+
if (idx !== -1) {
|
|
3397
|
+
waitQueue.splice(idx, 1);
|
|
3398
|
+
check();
|
|
3399
|
+
}
|
|
3400
|
+
}, waitTime);
|
|
3401
|
+
}
|
|
3402
|
+
};
|
|
3403
|
+
check();
|
|
3404
|
+
});
|
|
3405
|
+
}
|
|
3406
|
+
return {
|
|
3407
|
+
async execute(operation) {
|
|
3408
|
+
const waitTime = tryConsume();
|
|
3409
|
+
if (waitTime > 0) {
|
|
3410
|
+
if (strategy === "reject") {
|
|
3411
|
+
throw {
|
|
3412
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3413
|
+
limiterName: name,
|
|
3414
|
+
retryAfterMs: waitTime
|
|
3415
|
+
};
|
|
3416
|
+
}
|
|
3417
|
+
await waitForToken();
|
|
3418
|
+
}
|
|
3419
|
+
return operation();
|
|
3420
|
+
},
|
|
3421
|
+
async executeResult(operation) {
|
|
3422
|
+
const waitTime = tryConsume();
|
|
3423
|
+
if (waitTime > 0) {
|
|
3424
|
+
if (strategy === "reject") {
|
|
3425
|
+
return err2({
|
|
3426
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3427
|
+
limiterName: name,
|
|
3428
|
+
retryAfterMs: waitTime
|
|
3429
|
+
});
|
|
3430
|
+
}
|
|
3431
|
+
await waitForToken();
|
|
3432
|
+
}
|
|
3433
|
+
return operation();
|
|
3434
|
+
},
|
|
3435
|
+
getStats() {
|
|
3436
|
+
refill();
|
|
3437
|
+
return {
|
|
3438
|
+
availableTokens: Math.floor(tokens),
|
|
3439
|
+
maxTokens,
|
|
3440
|
+
tokensPerSecond: maxPerSecond,
|
|
3441
|
+
waitingCount: waitQueue.length
|
|
3442
|
+
};
|
|
3443
|
+
},
|
|
3444
|
+
reset() {
|
|
3445
|
+
tokens = maxTokens;
|
|
3446
|
+
lastRefill = Date.now();
|
|
3447
|
+
waitQueue.length = 0;
|
|
3448
|
+
}
|
|
3449
|
+
};
|
|
3450
|
+
}
|
|
3451
|
+
function createConcurrencyLimiter(name, config) {
|
|
3452
|
+
const { maxConcurrent, strategy = "queue", maxQueueSize = Infinity } = config;
|
|
3453
|
+
let activeCount = 0;
|
|
3454
|
+
const queue = [];
|
|
3455
|
+
async function acquire() {
|
|
3456
|
+
if (activeCount < maxConcurrent) {
|
|
3457
|
+
activeCount++;
|
|
3458
|
+
return;
|
|
3459
|
+
}
|
|
3460
|
+
if (strategy === "reject") {
|
|
3461
|
+
throw {
|
|
3462
|
+
type: "QUEUE_FULL",
|
|
3463
|
+
limiterName: name,
|
|
3464
|
+
queueSize: queue.length,
|
|
3465
|
+
maxQueueSize
|
|
3466
|
+
};
|
|
3467
|
+
}
|
|
3468
|
+
if (queue.length >= maxQueueSize) {
|
|
3469
|
+
throw {
|
|
3470
|
+
type: "QUEUE_FULL",
|
|
3471
|
+
limiterName: name,
|
|
3472
|
+
queueSize: queue.length,
|
|
3473
|
+
maxQueueSize
|
|
3474
|
+
};
|
|
3475
|
+
}
|
|
3476
|
+
return new Promise((resolve, reject) => {
|
|
3477
|
+
queue.push({ resolve, reject });
|
|
3478
|
+
});
|
|
3479
|
+
}
|
|
3480
|
+
function release() {
|
|
3481
|
+
activeCount--;
|
|
3482
|
+
if (queue.length > 0 && activeCount < maxConcurrent) {
|
|
3483
|
+
activeCount++;
|
|
3484
|
+
const next = queue.shift();
|
|
3485
|
+
next?.resolve();
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
return {
|
|
3489
|
+
async execute(operation) {
|
|
3490
|
+
await acquire();
|
|
3491
|
+
try {
|
|
3492
|
+
return await operation();
|
|
3493
|
+
} finally {
|
|
3494
|
+
release();
|
|
3495
|
+
}
|
|
3496
|
+
},
|
|
3497
|
+
async executeAll(operations) {
|
|
3498
|
+
const results = new Array(operations.length);
|
|
3499
|
+
const executing = [];
|
|
3500
|
+
for (let i = 0; i < operations.length; i++) {
|
|
3501
|
+
const index = i;
|
|
3502
|
+
const promise = this.execute(operations[index]).then((result) => {
|
|
3503
|
+
results[index] = result;
|
|
3504
|
+
});
|
|
3505
|
+
executing.push(promise);
|
|
3506
|
+
}
|
|
3507
|
+
await Promise.all(executing);
|
|
3508
|
+
return results;
|
|
3509
|
+
},
|
|
3510
|
+
async executeResult(operation) {
|
|
3511
|
+
try {
|
|
3512
|
+
await acquire();
|
|
3513
|
+
} catch (error) {
|
|
3514
|
+
if (isQueueFullError(error)) {
|
|
3515
|
+
return err2(error);
|
|
3516
|
+
}
|
|
3517
|
+
throw error;
|
|
3518
|
+
}
|
|
3519
|
+
try {
|
|
3520
|
+
return await operation();
|
|
3521
|
+
} finally {
|
|
3522
|
+
release();
|
|
3523
|
+
}
|
|
3524
|
+
},
|
|
3525
|
+
getStats() {
|
|
3526
|
+
return {
|
|
3527
|
+
activeCount,
|
|
3528
|
+
maxConcurrent,
|
|
3529
|
+
queueSize: queue.length,
|
|
3530
|
+
maxQueueSize
|
|
3531
|
+
};
|
|
3532
|
+
},
|
|
3533
|
+
reset() {
|
|
3534
|
+
activeCount = 0;
|
|
3535
|
+
while (queue.length > 0) {
|
|
3536
|
+
const item = queue.shift();
|
|
3537
|
+
item?.reject(new Error("Limiter reset"));
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
};
|
|
3541
|
+
}
|
|
3542
|
+
function createCombinedLimiter(name, config) {
|
|
3543
|
+
const rate = config.rate ? createRateLimiter(`${name}-rate`, config.rate) : void 0;
|
|
3544
|
+
const concurrency = config.concurrency ? createConcurrencyLimiter(`${name}-concurrency`, config.concurrency) : void 0;
|
|
3545
|
+
return {
|
|
3546
|
+
rate,
|
|
3547
|
+
concurrency,
|
|
3548
|
+
async execute(operation) {
|
|
3549
|
+
let op = operation;
|
|
3550
|
+
if (rate) {
|
|
3551
|
+
const originalOp = op;
|
|
3552
|
+
op = () => rate.execute(originalOp);
|
|
3553
|
+
}
|
|
3554
|
+
if (concurrency) {
|
|
3555
|
+
return concurrency.execute(op);
|
|
3556
|
+
}
|
|
3557
|
+
return op();
|
|
3558
|
+
}
|
|
3559
|
+
};
|
|
3560
|
+
}
|
|
3561
|
+
function createFixedWindowLimiter(name, config) {
|
|
3562
|
+
const { limit, windowMs = 1e3, strategy = "wait" } = config;
|
|
3563
|
+
let windowStart = Date.now();
|
|
3564
|
+
let requestCount = 0;
|
|
3565
|
+
const waitQueue = [];
|
|
3566
|
+
function checkWindow() {
|
|
3567
|
+
const now = Date.now();
|
|
3568
|
+
const elapsed = now - windowStart;
|
|
3569
|
+
if (elapsed >= windowMs) {
|
|
3570
|
+
windowStart = now;
|
|
3571
|
+
requestCount = 0;
|
|
3572
|
+
return 0;
|
|
3573
|
+
}
|
|
3574
|
+
return windowMs - elapsed;
|
|
3575
|
+
}
|
|
3576
|
+
function tryConsume(cost) {
|
|
3577
|
+
const remainingMs = checkWindow();
|
|
3578
|
+
if (requestCount + cost <= limit) {
|
|
3579
|
+
requestCount += cost;
|
|
3580
|
+
return 0;
|
|
3581
|
+
}
|
|
3582
|
+
return remainingMs;
|
|
3583
|
+
}
|
|
3584
|
+
async function waitForWindow(cost) {
|
|
3585
|
+
return new Promise((resolve) => {
|
|
3586
|
+
const check = () => {
|
|
3587
|
+
const waitTime = tryConsume(cost);
|
|
3588
|
+
if (waitTime === 0) {
|
|
3589
|
+
resolve();
|
|
3590
|
+
} else {
|
|
3591
|
+
waitQueue.push({ resolve: check, cost });
|
|
3592
|
+
setTimeout(() => {
|
|
3593
|
+
const idx = waitQueue.findIndex((w) => w.resolve === check);
|
|
3594
|
+
if (idx !== -1) {
|
|
3595
|
+
waitQueue.splice(idx, 1);
|
|
3596
|
+
check();
|
|
3597
|
+
}
|
|
3598
|
+
}, waitTime);
|
|
3599
|
+
}
|
|
3600
|
+
};
|
|
3601
|
+
check();
|
|
3602
|
+
});
|
|
3603
|
+
}
|
|
3604
|
+
return {
|
|
3605
|
+
async execute(operation, cost = 1) {
|
|
3606
|
+
if (cost > limit) {
|
|
3607
|
+
throw {
|
|
3608
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3609
|
+
limiterName: name,
|
|
3610
|
+
retryAfterMs: windowMs
|
|
3611
|
+
};
|
|
3612
|
+
}
|
|
3613
|
+
const waitTime = tryConsume(cost);
|
|
3614
|
+
if (waitTime > 0) {
|
|
3615
|
+
if (strategy === "reject") {
|
|
3616
|
+
throw {
|
|
3617
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3618
|
+
limiterName: name,
|
|
3619
|
+
retryAfterMs: waitTime
|
|
3620
|
+
};
|
|
3621
|
+
}
|
|
3622
|
+
await waitForWindow(cost);
|
|
3623
|
+
}
|
|
3624
|
+
return operation();
|
|
3625
|
+
},
|
|
3626
|
+
async executeResult(operation, cost = 1) {
|
|
3627
|
+
if (cost > limit) {
|
|
3628
|
+
return err2({
|
|
3629
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3630
|
+
limiterName: name,
|
|
3631
|
+
retryAfterMs: windowMs
|
|
3632
|
+
});
|
|
3633
|
+
}
|
|
3634
|
+
const waitTime = tryConsume(cost);
|
|
3635
|
+
if (waitTime > 0) {
|
|
3636
|
+
if (strategy === "reject") {
|
|
3637
|
+
return err2({
|
|
3638
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3639
|
+
limiterName: name,
|
|
3640
|
+
retryAfterMs: waitTime
|
|
3641
|
+
});
|
|
3642
|
+
}
|
|
3643
|
+
await waitForWindow(cost);
|
|
3644
|
+
}
|
|
3645
|
+
return operation();
|
|
3646
|
+
},
|
|
3647
|
+
getStats() {
|
|
3648
|
+
const remainingMs = checkWindow();
|
|
3649
|
+
return {
|
|
3650
|
+
requestCount,
|
|
3651
|
+
limit,
|
|
3652
|
+
windowMs,
|
|
3653
|
+
remainingMs,
|
|
3654
|
+
waitingCount: waitQueue.length
|
|
3655
|
+
};
|
|
3656
|
+
},
|
|
3657
|
+
reset() {
|
|
3658
|
+
windowStart = Date.now();
|
|
3659
|
+
requestCount = 0;
|
|
3660
|
+
waitQueue.length = 0;
|
|
3661
|
+
}
|
|
3662
|
+
};
|
|
3663
|
+
}
|
|
3664
|
+
function createCostBasedRateLimiter(name, config) {
|
|
3665
|
+
const { tokensPerSecond, strategy = "wait" } = config;
|
|
3666
|
+
const maxTokens = config.maxTokens ?? tokensPerSecond * 2;
|
|
3667
|
+
let tokens = maxTokens;
|
|
3668
|
+
let lastRefill = Date.now();
|
|
3669
|
+
const refillRate = tokensPerSecond / 1e3;
|
|
3670
|
+
const waitQueue = [];
|
|
3671
|
+
function refill() {
|
|
3672
|
+
const now = Date.now();
|
|
3673
|
+
const elapsed = now - lastRefill;
|
|
3674
|
+
const tokensToAdd = elapsed * refillRate;
|
|
3675
|
+
tokens = Math.min(maxTokens, tokens + tokensToAdd);
|
|
3676
|
+
lastRefill = now;
|
|
3677
|
+
}
|
|
3678
|
+
function tryConsume(cost) {
|
|
3679
|
+
refill();
|
|
3680
|
+
if (tokens >= cost) {
|
|
3681
|
+
tokens -= cost;
|
|
3682
|
+
return 0;
|
|
3683
|
+
}
|
|
3684
|
+
const tokensNeeded = cost - tokens;
|
|
3685
|
+
return Math.ceil(tokensNeeded / refillRate);
|
|
3686
|
+
}
|
|
3687
|
+
async function waitForTokens(cost) {
|
|
3688
|
+
return new Promise((resolve) => {
|
|
3689
|
+
const check = () => {
|
|
3690
|
+
const waitTime = tryConsume(cost);
|
|
3691
|
+
if (waitTime === 0) {
|
|
3692
|
+
resolve();
|
|
3693
|
+
} else {
|
|
3694
|
+
waitQueue.push({ check, cost });
|
|
3695
|
+
setTimeout(() => {
|
|
3696
|
+
const idx = waitQueue.findIndex((w) => w.check === check);
|
|
3697
|
+
if (idx !== -1) {
|
|
3698
|
+
waitQueue.splice(idx, 1);
|
|
3699
|
+
check();
|
|
3700
|
+
}
|
|
3701
|
+
}, waitTime);
|
|
3702
|
+
}
|
|
3703
|
+
};
|
|
3704
|
+
check();
|
|
3705
|
+
});
|
|
3706
|
+
}
|
|
3707
|
+
return {
|
|
3708
|
+
async execute(operation, cost = 1) {
|
|
3709
|
+
if (cost > maxTokens) {
|
|
3710
|
+
throw {
|
|
3711
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3712
|
+
limiterName: name,
|
|
3713
|
+
retryAfterMs: Math.ceil(cost / refillRate)
|
|
3714
|
+
};
|
|
3715
|
+
}
|
|
3716
|
+
const waitTime = tryConsume(cost);
|
|
3717
|
+
if (waitTime > 0) {
|
|
3718
|
+
if (strategy === "reject") {
|
|
3719
|
+
throw {
|
|
3720
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3721
|
+
limiterName: name,
|
|
3722
|
+
retryAfterMs: waitTime
|
|
3723
|
+
};
|
|
3724
|
+
}
|
|
3725
|
+
await waitForTokens(cost);
|
|
3726
|
+
}
|
|
3727
|
+
return operation();
|
|
3728
|
+
},
|
|
3729
|
+
async executeResult(operation, cost = 1) {
|
|
3730
|
+
if (cost > maxTokens) {
|
|
3731
|
+
return err2({
|
|
3732
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3733
|
+
limiterName: name,
|
|
3734
|
+
retryAfterMs: Math.ceil(cost / refillRate)
|
|
3735
|
+
});
|
|
3736
|
+
}
|
|
3737
|
+
const waitTime = tryConsume(cost);
|
|
3738
|
+
if (waitTime > 0) {
|
|
3739
|
+
if (strategy === "reject") {
|
|
3740
|
+
return err2({
|
|
3741
|
+
type: "RATE_LIMIT_EXCEEDED",
|
|
3742
|
+
limiterName: name,
|
|
3743
|
+
retryAfterMs: waitTime
|
|
3744
|
+
});
|
|
3745
|
+
}
|
|
3746
|
+
await waitForTokens(cost);
|
|
3747
|
+
}
|
|
3748
|
+
return operation();
|
|
3749
|
+
},
|
|
3750
|
+
getStats() {
|
|
3751
|
+
refill();
|
|
3752
|
+
return {
|
|
3753
|
+
availableTokens: tokens,
|
|
3754
|
+
maxTokens,
|
|
3755
|
+
tokensPerSecond,
|
|
3756
|
+
waitingCount: waitQueue.length
|
|
3757
|
+
};
|
|
3758
|
+
},
|
|
3759
|
+
reset() {
|
|
3760
|
+
tokens = maxTokens;
|
|
3761
|
+
lastRefill = Date.now();
|
|
3762
|
+
waitQueue.length = 0;
|
|
3763
|
+
}
|
|
3764
|
+
};
|
|
3765
|
+
}
|
|
3766
|
+
var rateLimiterPresets = {
|
|
3767
|
+
/**
|
|
3768
|
+
* Typical API rate limit (10 req/s).
|
|
3769
|
+
*/
|
|
3770
|
+
api: {
|
|
3771
|
+
maxPerSecond: 10,
|
|
3772
|
+
burstCapacity: 20,
|
|
3773
|
+
strategy: "wait"
|
|
3774
|
+
},
|
|
3775
|
+
/**
|
|
3776
|
+
* Database pool limit (concurrent connections).
|
|
3777
|
+
*/
|
|
3778
|
+
database: {
|
|
3779
|
+
maxConcurrent: 10,
|
|
3780
|
+
strategy: "queue",
|
|
3781
|
+
maxQueueSize: 100
|
|
3782
|
+
},
|
|
3783
|
+
/**
|
|
3784
|
+
* Aggressive rate limit for external APIs (5 req/s).
|
|
3785
|
+
*/
|
|
3786
|
+
external: {
|
|
3787
|
+
maxPerSecond: 5,
|
|
3788
|
+
burstCapacity: 10,
|
|
3789
|
+
strategy: "wait"
|
|
3790
|
+
}
|
|
3791
|
+
};
|
|
3792
|
+
|
|
3793
|
+
// src/cache.ts
|
|
3794
|
+
function toMs2(duration) {
|
|
3795
|
+
if (typeof duration === "string") {
|
|
3796
|
+
const parsed = parse(duration);
|
|
3797
|
+
if (!parsed) {
|
|
3798
|
+
throw new Error(`Invalid duration string: ${duration}`);
|
|
3799
|
+
}
|
|
3800
|
+
return parsed.millis;
|
|
3801
|
+
}
|
|
3802
|
+
return duration.millis;
|
|
3803
|
+
}
|
|
3804
|
+
function cached(fn) {
|
|
3805
|
+
let state = { status: "empty" };
|
|
3806
|
+
return async () => {
|
|
3807
|
+
if (state.status === "filled") {
|
|
3808
|
+
return state.value;
|
|
3809
|
+
}
|
|
3810
|
+
if (state.status === "pending") {
|
|
3811
|
+
return state.promise;
|
|
3812
|
+
}
|
|
3813
|
+
const promise = Promise.resolve(fn()).then((value) => {
|
|
3814
|
+
state = { status: "filled", value };
|
|
3815
|
+
return value;
|
|
3816
|
+
});
|
|
3817
|
+
state = { status: "pending", promise };
|
|
3818
|
+
return promise;
|
|
3819
|
+
};
|
|
3820
|
+
}
|
|
3821
|
+
function cachedWithTTL(fn, options) {
|
|
3822
|
+
const ttlMs = toMs2(options.ttl);
|
|
3823
|
+
let state = { status: "empty" };
|
|
3824
|
+
return async () => {
|
|
3825
|
+
const now = Date.now();
|
|
3826
|
+
if (state.status === "filled" && now < state.expiresAt) {
|
|
3827
|
+
return state.value;
|
|
3828
|
+
}
|
|
3829
|
+
if (state.status === "pending") {
|
|
3830
|
+
return state.promise;
|
|
3831
|
+
}
|
|
3832
|
+
const promise = Promise.resolve(fn()).then((value) => {
|
|
3833
|
+
state = {
|
|
3834
|
+
status: "filled",
|
|
3835
|
+
value,
|
|
3836
|
+
expiresAt: Date.now() + ttlMs
|
|
3837
|
+
};
|
|
3838
|
+
return value;
|
|
3839
|
+
});
|
|
3840
|
+
state = { status: "pending", promise };
|
|
3841
|
+
return promise;
|
|
3842
|
+
};
|
|
3843
|
+
}
|
|
3844
|
+
function cachedFunction(fn, options = {}) {
|
|
3845
|
+
const {
|
|
3846
|
+
keyFn = (...args) => JSON.stringify(args),
|
|
3847
|
+
maxSize = Infinity
|
|
3848
|
+
} = options;
|
|
3849
|
+
const ttlMs = options.ttl ? toMs2(options.ttl) : void 0;
|
|
3850
|
+
const cache = /* @__PURE__ */ new Map();
|
|
3851
|
+
const pending = /* @__PURE__ */ new Map();
|
|
3852
|
+
let hits = 0;
|
|
3853
|
+
let misses = 0;
|
|
3854
|
+
function evictOldest() {
|
|
3855
|
+
if (cache.size <= maxSize) return;
|
|
3856
|
+
let oldestKey = null;
|
|
3857
|
+
let oldestTime = Infinity;
|
|
3858
|
+
for (const [key, entry] of cache.entries()) {
|
|
3859
|
+
if (entry.timestamp < oldestTime) {
|
|
3860
|
+
oldestTime = entry.timestamp;
|
|
3861
|
+
oldestKey = key;
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3864
|
+
if (oldestKey) {
|
|
3865
|
+
cache.delete(oldestKey);
|
|
3866
|
+
}
|
|
3867
|
+
}
|
|
3868
|
+
const memoized = async (...args) => {
|
|
3869
|
+
const key = keyFn(...args);
|
|
3870
|
+
const now = Date.now();
|
|
3871
|
+
const cached2 = cache.get(key);
|
|
3872
|
+
if (cached2) {
|
|
3873
|
+
if (cached2.expiresAt && now >= cached2.expiresAt) {
|
|
3874
|
+
cache.delete(key);
|
|
3875
|
+
} else {
|
|
3876
|
+
hits++;
|
|
3877
|
+
return cached2.value;
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
const pendingPromise = pending.get(key);
|
|
3881
|
+
if (pendingPromise) {
|
|
3882
|
+
return pendingPromise;
|
|
3883
|
+
}
|
|
3884
|
+
misses++;
|
|
3885
|
+
const promise = Promise.resolve(fn(...args)).then((value) => {
|
|
3886
|
+
const entry = {
|
|
3887
|
+
value,
|
|
3888
|
+
timestamp: Date.now(),
|
|
3889
|
+
expiresAt: ttlMs ? Date.now() + ttlMs : void 0
|
|
3890
|
+
};
|
|
3891
|
+
cache.set(key, entry);
|
|
3892
|
+
pending.delete(key);
|
|
3893
|
+
evictOldest();
|
|
3894
|
+
return value;
|
|
3895
|
+
});
|
|
3896
|
+
pending.set(key, promise);
|
|
3897
|
+
try {
|
|
3898
|
+
return await promise;
|
|
3899
|
+
} catch (error) {
|
|
3900
|
+
pending.delete(key);
|
|
3901
|
+
throw error;
|
|
3902
|
+
}
|
|
3903
|
+
};
|
|
3904
|
+
memoized.clear = () => {
|
|
3905
|
+
cache.clear();
|
|
3906
|
+
pending.clear();
|
|
3907
|
+
};
|
|
3908
|
+
memoized.delete = (...args) => {
|
|
3909
|
+
const key = keyFn(...args);
|
|
3910
|
+
return cache.delete(key);
|
|
3911
|
+
};
|
|
3912
|
+
memoized.has = (...args) => {
|
|
3913
|
+
const key = keyFn(...args);
|
|
3914
|
+
const entry = cache.get(key);
|
|
3915
|
+
if (!entry) return false;
|
|
3916
|
+
if (entry.expiresAt && Date.now() >= entry.expiresAt) {
|
|
3917
|
+
cache.delete(key);
|
|
3918
|
+
return false;
|
|
3919
|
+
}
|
|
3920
|
+
return true;
|
|
3921
|
+
};
|
|
3922
|
+
memoized.getStats = () => ({
|
|
3923
|
+
hits,
|
|
3924
|
+
misses,
|
|
3925
|
+
size: cache.size
|
|
3926
|
+
});
|
|
3927
|
+
return memoized;
|
|
3928
|
+
}
|
|
3929
|
+
function once(fn) {
|
|
3930
|
+
let state = { status: "idle" };
|
|
3931
|
+
const onceFn = async () => {
|
|
3932
|
+
if (state.status === "done") {
|
|
3933
|
+
return state.value;
|
|
3934
|
+
}
|
|
3935
|
+
if (state.status === "failed") {
|
|
3936
|
+
throw state.error;
|
|
3937
|
+
}
|
|
3938
|
+
if (state.status === "running") {
|
|
3939
|
+
return state.promise;
|
|
3940
|
+
}
|
|
3941
|
+
const promise = Promise.resolve(fn()).then((value) => {
|
|
3942
|
+
state = { status: "done", value };
|
|
3943
|
+
return value;
|
|
3944
|
+
}).catch((error) => {
|
|
3945
|
+
state = { status: "failed", error };
|
|
3946
|
+
throw error;
|
|
3947
|
+
});
|
|
3948
|
+
state = { status: "running", promise };
|
|
3949
|
+
return promise;
|
|
3950
|
+
};
|
|
3951
|
+
Object.defineProperty(onceFn, "called", {
|
|
3952
|
+
get: () => state.status !== "idle"
|
|
3953
|
+
});
|
|
3954
|
+
Object.defineProperty(onceFn, "completed", {
|
|
3955
|
+
get: () => state.status === "done"
|
|
3956
|
+
});
|
|
3957
|
+
Object.defineProperty(onceFn, "failed", {
|
|
3958
|
+
get: () => state.status === "failed"
|
|
3959
|
+
});
|
|
3960
|
+
onceFn.reset = () => {
|
|
3961
|
+
state = { status: "idle" };
|
|
3962
|
+
};
|
|
3963
|
+
return onceFn;
|
|
3964
|
+
}
|
|
3965
|
+
function createCache(config = {}) {
|
|
3966
|
+
const { maxSize = Infinity } = config;
|
|
3967
|
+
const defaultTTLMs = config.defaultTTL ? toMs2(config.defaultTTL) : void 0;
|
|
3968
|
+
const store = /* @__PURE__ */ new Map();
|
|
3969
|
+
let hits = 0;
|
|
3970
|
+
let misses = 0;
|
|
3971
|
+
function isExpired(entry) {
|
|
3972
|
+
return entry.expiresAt !== void 0 && Date.now() >= entry.expiresAt;
|
|
3973
|
+
}
|
|
3974
|
+
function evictOldest() {
|
|
3975
|
+
if (store.size <= maxSize) return;
|
|
3976
|
+
let oldestKey = null;
|
|
3977
|
+
let oldestTime = Infinity;
|
|
3978
|
+
for (const [key, entry] of store.entries()) {
|
|
3979
|
+
if (entry.timestamp < oldestTime) {
|
|
3980
|
+
oldestTime = entry.timestamp;
|
|
3981
|
+
oldestKey = key;
|
|
3982
|
+
}
|
|
3983
|
+
}
|
|
3984
|
+
if (oldestKey !== null) {
|
|
3985
|
+
store.delete(oldestKey);
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
return {
|
|
3989
|
+
get(key) {
|
|
3990
|
+
const entry = store.get(key);
|
|
3991
|
+
if (!entry) {
|
|
3992
|
+
misses++;
|
|
3993
|
+
return void 0;
|
|
3994
|
+
}
|
|
3995
|
+
if (isExpired(entry)) {
|
|
3996
|
+
store.delete(key);
|
|
3997
|
+
misses++;
|
|
3998
|
+
return void 0;
|
|
3999
|
+
}
|
|
4000
|
+
hits++;
|
|
4001
|
+
return entry.value;
|
|
4002
|
+
},
|
|
4003
|
+
set(key, value, options) {
|
|
4004
|
+
const ttlMs = options?.ttl ? toMs2(options.ttl) : defaultTTLMs;
|
|
4005
|
+
const now = Date.now();
|
|
4006
|
+
store.set(key, {
|
|
4007
|
+
value,
|
|
4008
|
+
timestamp: now,
|
|
4009
|
+
expiresAt: ttlMs ? now + ttlMs : void 0
|
|
4010
|
+
});
|
|
4011
|
+
evictOldest();
|
|
4012
|
+
},
|
|
4013
|
+
has(key) {
|
|
4014
|
+
const entry = store.get(key);
|
|
4015
|
+
if (!entry) return false;
|
|
4016
|
+
if (isExpired(entry)) {
|
|
4017
|
+
store.delete(key);
|
|
4018
|
+
return false;
|
|
4019
|
+
}
|
|
4020
|
+
return true;
|
|
4021
|
+
},
|
|
4022
|
+
delete(key) {
|
|
4023
|
+
return store.delete(key);
|
|
4024
|
+
},
|
|
4025
|
+
clear() {
|
|
4026
|
+
store.clear();
|
|
4027
|
+
},
|
|
4028
|
+
get size() {
|
|
4029
|
+
return store.size;
|
|
4030
|
+
},
|
|
4031
|
+
getStats() {
|
|
4032
|
+
return { hits, misses, size: store.size };
|
|
4033
|
+
}
|
|
4034
|
+
};
|
|
4035
|
+
}
|
|
4036
|
+
|
|
4037
|
+
// src/singleflight.ts
|
|
4038
|
+
function singleflight(operation, options) {
|
|
4039
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
4040
|
+
const cache = options.ttl ? /* @__PURE__ */ new Map() : null;
|
|
4041
|
+
return async (...args) => {
|
|
4042
|
+
const key = options.key(...args);
|
|
4043
|
+
if (cache) {
|
|
4044
|
+
const cached2 = cache.get(key);
|
|
4045
|
+
if (cached2 && cached2.expiresAt > Date.now()) {
|
|
4046
|
+
return cached2.result;
|
|
4047
|
+
}
|
|
4048
|
+
if (cached2) {
|
|
4049
|
+
cache.delete(key);
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
const existing = inflight.get(key);
|
|
4053
|
+
if (existing) {
|
|
4054
|
+
return existing;
|
|
4055
|
+
}
|
|
4056
|
+
const promise = operation(...args).then((result) => {
|
|
4057
|
+
if (cache && options.ttl && result.ok) {
|
|
4058
|
+
cache.set(key, {
|
|
4059
|
+
result,
|
|
4060
|
+
expiresAt: Date.now() + options.ttl
|
|
4061
|
+
});
|
|
4062
|
+
}
|
|
4063
|
+
return result;
|
|
4064
|
+
}).finally(() => {
|
|
4065
|
+
inflight.delete(key);
|
|
4066
|
+
});
|
|
4067
|
+
inflight.set(key, promise);
|
|
4068
|
+
return promise;
|
|
4069
|
+
};
|
|
4070
|
+
}
|
|
4071
|
+
function createSingleflightGroup() {
|
|
4072
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
4073
|
+
return {
|
|
4074
|
+
execute: async (key, operation) => {
|
|
4075
|
+
const existing = inflight.get(key);
|
|
4076
|
+
if (existing) {
|
|
4077
|
+
return existing;
|
|
4078
|
+
}
|
|
4079
|
+
const promise = operation().then((result) => result).finally(() => {
|
|
4080
|
+
inflight.delete(key);
|
|
4081
|
+
});
|
|
4082
|
+
inflight.set(key, promise);
|
|
4083
|
+
return promise;
|
|
4084
|
+
},
|
|
4085
|
+
isInflight: (key) => inflight.has(key),
|
|
4086
|
+
size: () => inflight.size,
|
|
4087
|
+
clear: () => inflight.clear()
|
|
4088
|
+
};
|
|
4089
|
+
}
|
|
4090
|
+
|
|
4091
|
+
// src/policies.ts
|
|
4092
|
+
function mergePolicies(...policies) {
|
|
4093
|
+
const result = {};
|
|
4094
|
+
for (const policy of policies) {
|
|
4095
|
+
if (policy.key !== void 0) result.key = policy.key;
|
|
4096
|
+
if (policy.retry !== void 0) {
|
|
4097
|
+
result.retry = result.retry ? { ...result.retry, ...policy.retry } : { ...policy.retry };
|
|
4098
|
+
}
|
|
4099
|
+
if (policy.timeout !== void 0) {
|
|
4100
|
+
result.timeout = result.timeout ? { ...result.timeout, ...policy.timeout } : { ...policy.timeout };
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
return result;
|
|
4104
|
+
}
|
|
4105
|
+
function createPolicyApplier(...basePolicies) {
|
|
4106
|
+
const basePolicy = mergePolicies(...basePolicies);
|
|
4107
|
+
return (stepOptions2) => {
|
|
4108
|
+
const opts = stepOptions2 ?? {};
|
|
4109
|
+
return mergePolicies(basePolicy, opts);
|
|
4110
|
+
};
|
|
4111
|
+
}
|
|
4112
|
+
function createPolicyBundle(name, ...policies) {
|
|
4113
|
+
return {
|
|
4114
|
+
name,
|
|
4115
|
+
policy: mergePolicies(...policies)
|
|
4116
|
+
};
|
|
4117
|
+
}
|
|
4118
|
+
function retryPolicy(options) {
|
|
4119
|
+
return { retry: options };
|
|
4120
|
+
}
|
|
4121
|
+
var retryPolicies = {
|
|
4122
|
+
/**
|
|
4123
|
+
* No retry - fail immediately on error.
|
|
4124
|
+
*/
|
|
4125
|
+
none: retryPolicy({ attempts: 1 }),
|
|
4126
|
+
/**
|
|
4127
|
+
* Quick retry for transient errors (3 attempts, fast backoff).
|
|
4128
|
+
*/
|
|
4129
|
+
transient: retryPolicy({
|
|
4130
|
+
attempts: 3,
|
|
4131
|
+
backoff: "exponential",
|
|
4132
|
+
initialDelay: 100,
|
|
4133
|
+
maxDelay: 1e3,
|
|
4134
|
+
jitter: true
|
|
4135
|
+
}),
|
|
4136
|
+
/**
|
|
4137
|
+
* Standard retry for API calls (3 attempts, moderate backoff).
|
|
4138
|
+
*/
|
|
4139
|
+
standard: retryPolicy({
|
|
4140
|
+
attempts: 3,
|
|
4141
|
+
backoff: "exponential",
|
|
4142
|
+
initialDelay: 200,
|
|
4143
|
+
maxDelay: 5e3,
|
|
4144
|
+
jitter: true
|
|
4145
|
+
}),
|
|
4146
|
+
/**
|
|
4147
|
+
* Aggressive retry for critical operations (5 attempts, longer backoff).
|
|
4148
|
+
*/
|
|
4149
|
+
aggressive: retryPolicy({
|
|
4150
|
+
attempts: 5,
|
|
4151
|
+
backoff: "exponential",
|
|
4152
|
+
initialDelay: 500,
|
|
4153
|
+
maxDelay: 3e4,
|
|
4154
|
+
jitter: true
|
|
4155
|
+
}),
|
|
4156
|
+
/**
|
|
4157
|
+
* Fixed interval retry (useful for polling).
|
|
4158
|
+
*/
|
|
4159
|
+
fixed: (attempts, delayMs) => retryPolicy({
|
|
4160
|
+
attempts,
|
|
4161
|
+
backoff: "fixed",
|
|
4162
|
+
initialDelay: delayMs,
|
|
4163
|
+
jitter: false
|
|
4164
|
+
}),
|
|
4165
|
+
/**
|
|
4166
|
+
* Linear backoff retry.
|
|
4167
|
+
*/
|
|
4168
|
+
linear: (attempts, initialDelay) => retryPolicy({
|
|
4169
|
+
attempts,
|
|
4170
|
+
backoff: "linear",
|
|
4171
|
+
initialDelay,
|
|
4172
|
+
jitter: true
|
|
4173
|
+
}),
|
|
4174
|
+
/**
|
|
4175
|
+
* Custom retry policy builder.
|
|
4176
|
+
*/
|
|
4177
|
+
custom: (options) => retryPolicy({
|
|
4178
|
+
backoff: "exponential",
|
|
4179
|
+
initialDelay: 100,
|
|
4180
|
+
maxDelay: 3e4,
|
|
4181
|
+
jitter: true,
|
|
4182
|
+
...options
|
|
4183
|
+
})
|
|
4184
|
+
};
|
|
4185
|
+
function timeoutPolicy(options) {
|
|
4186
|
+
return { timeout: options };
|
|
4187
|
+
}
|
|
4188
|
+
var timeoutPolicies = {
|
|
4189
|
+
/**
|
|
4190
|
+
* No timeout.
|
|
4191
|
+
*/
|
|
4192
|
+
none: {},
|
|
4193
|
+
/**
|
|
4194
|
+
* Fast timeout for quick operations (1 second).
|
|
4195
|
+
*/
|
|
4196
|
+
fast: timeoutPolicy({ ms: 1e3 }),
|
|
4197
|
+
/**
|
|
4198
|
+
* Standard API timeout (5 seconds).
|
|
4199
|
+
*/
|
|
4200
|
+
api: timeoutPolicy({ ms: 5e3 }),
|
|
4201
|
+
/**
|
|
4202
|
+
* Extended timeout for slower operations (30 seconds).
|
|
4203
|
+
*/
|
|
4204
|
+
extended: timeoutPolicy({ ms: 3e4 }),
|
|
4205
|
+
/**
|
|
4206
|
+
* Long timeout for batch operations (2 minutes).
|
|
4207
|
+
*/
|
|
4208
|
+
long: timeoutPolicy({ ms: 12e4 }),
|
|
4209
|
+
/**
|
|
4210
|
+
* Custom timeout in milliseconds.
|
|
4211
|
+
*/
|
|
4212
|
+
ms: (ms) => timeoutPolicy({ ms }),
|
|
4213
|
+
/**
|
|
4214
|
+
* Custom timeout in seconds.
|
|
4215
|
+
*/
|
|
4216
|
+
seconds: (seconds2) => timeoutPolicy({ ms: seconds2 * 1e3 }),
|
|
4217
|
+
/**
|
|
4218
|
+
* Timeout with custom error.
|
|
4219
|
+
*/
|
|
4220
|
+
withError: (ms, error) => timeoutPolicy({ ms, error }),
|
|
4221
|
+
/**
|
|
4222
|
+
* Timeout with AbortSignal support.
|
|
4223
|
+
*/
|
|
4224
|
+
withSignal: (ms) => timeoutPolicy({ ms, signal: true })
|
|
4225
|
+
};
|
|
4226
|
+
var servicePolicies = {
|
|
4227
|
+
/**
|
|
4228
|
+
* Policy for external HTTP APIs.
|
|
4229
|
+
* - 5 second timeout
|
|
4230
|
+
* - 3 retries with exponential backoff
|
|
4231
|
+
*/
|
|
4232
|
+
httpApi: mergePolicies(
|
|
4233
|
+
timeoutPolicies.api,
|
|
4234
|
+
retryPolicies.standard
|
|
4235
|
+
),
|
|
4236
|
+
/**
|
|
4237
|
+
* Policy for database operations.
|
|
4238
|
+
* - 30 second timeout
|
|
4239
|
+
* - 2 retries for transient errors
|
|
4240
|
+
*/
|
|
4241
|
+
database: mergePolicies(
|
|
4242
|
+
timeoutPolicies.extended,
|
|
4243
|
+
retryPolicy({
|
|
4244
|
+
attempts: 2,
|
|
4245
|
+
backoff: "exponential",
|
|
4246
|
+
initialDelay: 100,
|
|
4247
|
+
maxDelay: 2e3,
|
|
4248
|
+
jitter: true
|
|
4249
|
+
})
|
|
4250
|
+
),
|
|
4251
|
+
/**
|
|
4252
|
+
* Policy for cache operations.
|
|
4253
|
+
* - 1 second timeout
|
|
4254
|
+
* - No retry (cache misses are not errors)
|
|
4255
|
+
*/
|
|
4256
|
+
cache: mergePolicies(
|
|
4257
|
+
timeoutPolicies.fast,
|
|
4258
|
+
retryPolicies.none
|
|
4259
|
+
),
|
|
4260
|
+
/**
|
|
4261
|
+
* Policy for message queue operations.
|
|
4262
|
+
* - 30 second timeout
|
|
4263
|
+
* - 5 retries with longer backoff
|
|
4264
|
+
*/
|
|
4265
|
+
messageQueue: mergePolicies(
|
|
4266
|
+
timeoutPolicies.extended,
|
|
4267
|
+
retryPolicies.aggressive
|
|
4268
|
+
),
|
|
4269
|
+
/**
|
|
4270
|
+
* Policy for file operations.
|
|
4271
|
+
* - 2 minute timeout
|
|
4272
|
+
* - 3 retries
|
|
4273
|
+
*/
|
|
4274
|
+
fileSystem: mergePolicies(
|
|
4275
|
+
timeoutPolicies.long,
|
|
4276
|
+
retryPolicies.standard
|
|
4277
|
+
),
|
|
4278
|
+
/**
|
|
4279
|
+
* Policy for third-party services with rate limits.
|
|
4280
|
+
* - 10 second timeout
|
|
4281
|
+
* - 5 retries with linear backoff
|
|
4282
|
+
*/
|
|
4283
|
+
rateLimited: mergePolicies(
|
|
4284
|
+
timeoutPolicy({ ms: 1e4 }),
|
|
4285
|
+
retryPolicy({
|
|
4286
|
+
attempts: 5,
|
|
4287
|
+
backoff: "linear",
|
|
4288
|
+
initialDelay: 1e3,
|
|
4289
|
+
maxDelay: 1e4,
|
|
4290
|
+
jitter: true
|
|
4291
|
+
})
|
|
4292
|
+
)
|
|
4293
|
+
};
|
|
4294
|
+
function withPolicy(policy, stepOptions2) {
|
|
4295
|
+
const opts = stepOptions2 ?? {};
|
|
4296
|
+
return mergePolicies(policy, opts);
|
|
4297
|
+
}
|
|
4298
|
+
function withPolicies(policies, stepOptions2) {
|
|
4299
|
+
const opts = stepOptions2 ?? {};
|
|
4300
|
+
return mergePolicies(...policies, opts);
|
|
4301
|
+
}
|
|
4302
|
+
function conditionalPolicy(condition, policy, elsePolicy = {}) {
|
|
4303
|
+
return condition ? policy : elsePolicy;
|
|
4304
|
+
}
|
|
4305
|
+
function envPolicy(envPolicies, currentEnv = process.env.NODE_ENV ?? "development", defaultPolicy = {}) {
|
|
4306
|
+
return envPolicies[currentEnv] ?? defaultPolicy;
|
|
4307
|
+
}
|
|
4308
|
+
function createPolicyRegistry() {
|
|
4309
|
+
const policies = /* @__PURE__ */ new Map();
|
|
4310
|
+
return {
|
|
4311
|
+
register(name, policy) {
|
|
4312
|
+
policies.set(name, policy);
|
|
4313
|
+
},
|
|
4314
|
+
get(name) {
|
|
4315
|
+
return policies.get(name);
|
|
4316
|
+
},
|
|
4317
|
+
has(name) {
|
|
4318
|
+
return policies.has(name);
|
|
4319
|
+
},
|
|
4320
|
+
names() {
|
|
4321
|
+
return Array.from(policies.keys());
|
|
4322
|
+
},
|
|
4323
|
+
apply(policyName, stepOptions2) {
|
|
4324
|
+
const policy = policies.get(policyName);
|
|
4325
|
+
if (!policy) {
|
|
4326
|
+
throw new Error(`Policy not found: ${policyName}`);
|
|
4327
|
+
}
|
|
4328
|
+
return withPolicy(policy, stepOptions2);
|
|
4329
|
+
}
|
|
4330
|
+
};
|
|
4331
|
+
}
|
|
4332
|
+
function stepOptions() {
|
|
4333
|
+
const policies = [];
|
|
4334
|
+
const builder = {
|
|
4335
|
+
key(key) {
|
|
4336
|
+
policies.push({ key });
|
|
4337
|
+
return builder;
|
|
4338
|
+
},
|
|
4339
|
+
policy(policy) {
|
|
4340
|
+
policies.push(policy);
|
|
4341
|
+
return builder;
|
|
4342
|
+
},
|
|
4343
|
+
timeout(ms) {
|
|
4344
|
+
policies.push(timeoutPolicy({ ms }));
|
|
4345
|
+
return builder;
|
|
4346
|
+
},
|
|
4347
|
+
retry(options) {
|
|
4348
|
+
policies.push(retryPolicy(options));
|
|
4349
|
+
return builder;
|
|
4350
|
+
},
|
|
4351
|
+
retries(attempts) {
|
|
4352
|
+
policies.push(retryPolicies.custom({ attempts }));
|
|
4353
|
+
return builder;
|
|
4354
|
+
},
|
|
4355
|
+
build() {
|
|
4356
|
+
return mergePolicies(...policies);
|
|
4357
|
+
}
|
|
4358
|
+
};
|
|
4359
|
+
return builder;
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
// src/conditional.ts
|
|
4363
|
+
function generateDecisionId() {
|
|
4364
|
+
return `decision_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
4365
|
+
}
|
|
4366
|
+
function emitSkipped(ctx, options, decisionId) {
|
|
4367
|
+
if (!ctx?.onEvent) return;
|
|
4368
|
+
const event = {
|
|
4369
|
+
type: "step_skipped",
|
|
4370
|
+
workflowId: ctx.workflowId,
|
|
4371
|
+
stepKey: options?.key,
|
|
4372
|
+
name: options?.name,
|
|
4373
|
+
reason: options?.reason,
|
|
4374
|
+
decisionId,
|
|
4375
|
+
ts: Date.now()
|
|
4376
|
+
};
|
|
4377
|
+
const eventWithContext = event.context !== void 0 || ctx.context === void 0 ? event : { ...event, context: ctx.context };
|
|
4378
|
+
ctx.onEvent(eventWithContext);
|
|
4379
|
+
}
|
|
4380
|
+
function when2(condition, operation, options, ctx) {
|
|
4381
|
+
if (condition) {
|
|
4382
|
+
return operation();
|
|
4383
|
+
}
|
|
4384
|
+
const decisionId = generateDecisionId();
|
|
4385
|
+
emitSkipped(ctx, options, decisionId);
|
|
4386
|
+
return void 0;
|
|
4387
|
+
}
|
|
4388
|
+
function unless(condition, operation, options, ctx) {
|
|
4389
|
+
return when2(!condition, operation, options, ctx);
|
|
4390
|
+
}
|
|
4391
|
+
function whenOr(condition, operation, defaultValue, options, ctx) {
|
|
4392
|
+
if (condition) {
|
|
4393
|
+
return operation();
|
|
4394
|
+
}
|
|
4395
|
+
const decisionId = generateDecisionId();
|
|
4396
|
+
emitSkipped(ctx, options, decisionId);
|
|
4397
|
+
return defaultValue;
|
|
4398
|
+
}
|
|
4399
|
+
function unlessOr(condition, operation, defaultValue, options, ctx) {
|
|
4400
|
+
return whenOr(!condition, operation, defaultValue, options, ctx);
|
|
4401
|
+
}
|
|
4402
|
+
function createConditionalHelpers(ctx) {
|
|
4403
|
+
return {
|
|
4404
|
+
/**
|
|
4405
|
+
* Run a step only if condition is true, return undefined if skipped.
|
|
4406
|
+
*/
|
|
4407
|
+
when: (condition, operation, options) => when2(condition, operation, options, ctx),
|
|
4408
|
+
/**
|
|
4409
|
+
* Run a step only if condition is false, return undefined if skipped.
|
|
4410
|
+
*/
|
|
4411
|
+
unless: (condition, operation, options) => unless(condition, operation, options, ctx),
|
|
4412
|
+
/**
|
|
4413
|
+
* Run a step only if condition is true, return default value if skipped.
|
|
4414
|
+
*/
|
|
4415
|
+
whenOr: (condition, operation, defaultValue, options) => whenOr(condition, operation, defaultValue, options, ctx),
|
|
4416
|
+
/**
|
|
4417
|
+
* Run a step only if condition is false, return default value if skipped.
|
|
4418
|
+
*/
|
|
4419
|
+
unlessOr: (condition, operation, defaultValue, options) => unlessOr(condition, operation, defaultValue, options, ctx)
|
|
4420
|
+
};
|
|
4421
|
+
}
|
|
4422
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
4423
|
+
0 && (module.exports = {
|
|
4424
|
+
ALL_SLUGS,
|
|
4425
|
+
AWAITLY_CANCELLED,
|
|
4426
|
+
AWAITLY_SLUGS,
|
|
4427
|
+
AWAITLY_SYSTEM_ERROR_CLASSES,
|
|
4428
|
+
AWAITLY_TIMEOUT,
|
|
4429
|
+
AWAITLY_UNEXPECTED,
|
|
4430
|
+
CircuitBreakerOpenError,
|
|
4431
|
+
CircuitOpenError,
|
|
4432
|
+
CompensationError,
|
|
4433
|
+
DESERIALIZATION_ERROR,
|
|
4434
|
+
Duration,
|
|
4435
|
+
EARLY_EXIT_SYMBOL,
|
|
4436
|
+
Match,
|
|
4437
|
+
NetworkError,
|
|
4438
|
+
NotFoundError,
|
|
4439
|
+
PROMISE_REJECTED,
|
|
4440
|
+
RateLimitError,
|
|
4441
|
+
RetryExhaustedError,
|
|
4442
|
+
STEP_TIMEOUT_MARKER,
|
|
4443
|
+
TaggedError,
|
|
4444
|
+
TimeoutError,
|
|
4445
|
+
UnauthorizedError,
|
|
4446
|
+
UnexpectedError,
|
|
4447
|
+
UnwrapError,
|
|
4448
|
+
ValidationError,
|
|
4449
|
+
add,
|
|
4450
|
+
all,
|
|
4451
|
+
allAsync,
|
|
4452
|
+
allSettled,
|
|
4453
|
+
allSettledAsync,
|
|
4454
|
+
andThen,
|
|
4455
|
+
any,
|
|
4456
|
+
anyAsync,
|
|
4457
|
+
bimap,
|
|
4458
|
+
cached,
|
|
4459
|
+
cachedFunction,
|
|
4460
|
+
cachedWithTTL,
|
|
4461
|
+
circuitBreakerPresets,
|
|
4462
|
+
clamp,
|
|
4463
|
+
conditionalPolicy,
|
|
4464
|
+
createCache,
|
|
4465
|
+
createCircuitBreaker,
|
|
4466
|
+
createCombinedLimiter,
|
|
4467
|
+
createConcurrencyLimiter,
|
|
4468
|
+
createConditionalHelpers,
|
|
4469
|
+
createCostBasedRateLimiter,
|
|
4470
|
+
createEarlyExit,
|
|
4471
|
+
createFixedWindowLimiter,
|
|
4472
|
+
createPolicyApplier,
|
|
4473
|
+
createPolicyBundle,
|
|
4474
|
+
createPolicyRegistry,
|
|
4475
|
+
createRateLimiter,
|
|
4476
|
+
createSingleflightGroup,
|
|
4477
|
+
days,
|
|
4478
|
+
deserialize,
|
|
4479
|
+
divide,
|
|
4480
|
+
envPolicy,
|
|
4481
|
+
equals,
|
|
4482
|
+
err,
|
|
4483
|
+
exhaustive,
|
|
4484
|
+
fallback,
|
|
4485
|
+
flatten,
|
|
4486
|
+
format,
|
|
4487
|
+
from,
|
|
4488
|
+
fromNullable,
|
|
4489
|
+
fromPromise,
|
|
4490
|
+
getStepTimeoutMeta,
|
|
4491
|
+
greaterThan,
|
|
4492
|
+
greaterThanOrEqual,
|
|
4493
|
+
hours,
|
|
4494
|
+
hydrate,
|
|
4495
|
+
infinity,
|
|
4496
|
+
isAwaitlyError,
|
|
4497
|
+
isAwaitlySlug,
|
|
4498
|
+
isCircuitBreakerOpenError,
|
|
4499
|
+
isCircuitOpenError,
|
|
4500
|
+
isCompensationError,
|
|
4501
|
+
isDuration,
|
|
4502
|
+
isEarlyExit,
|
|
4503
|
+
isErr,
|
|
4504
|
+
isFinite,
|
|
4505
|
+
isInfinite,
|
|
4506
|
+
isNetworkError,
|
|
4507
|
+
isNotFoundError,
|
|
4508
|
+
isOk,
|
|
4509
|
+
isOneOf,
|
|
4510
|
+
isPromiseRejectedError,
|
|
4511
|
+
isQueueFullError,
|
|
4512
|
+
isRateLimitError,
|
|
4513
|
+
isRateLimitExceededError,
|
|
4514
|
+
isRetryExhaustedError,
|
|
4515
|
+
isSerializedResult,
|
|
4516
|
+
isStepTimeoutError,
|
|
4517
|
+
isTag,
|
|
4518
|
+
isTimeoutError,
|
|
4519
|
+
isUnauthorizedError,
|
|
4520
|
+
isUnexpectedError,
|
|
4521
|
+
isValidationError,
|
|
4522
|
+
isZero,
|
|
4523
|
+
lessThan,
|
|
4524
|
+
lessThanOrEqual,
|
|
4525
|
+
makeError,
|
|
4526
|
+
map,
|
|
4527
|
+
mapError,
|
|
4528
|
+
mapErrorTry,
|
|
4529
|
+
mapTry,
|
|
4530
|
+
match,
|
|
4531
|
+
matchError,
|
|
4532
|
+
matchErrorPartial,
|
|
4533
|
+
matchOrElse,
|
|
4534
|
+
matchTag,
|
|
4535
|
+
matchTags,
|
|
4536
|
+
matchValue,
|
|
4537
|
+
max,
|
|
4538
|
+
mergePolicies,
|
|
4539
|
+
millis,
|
|
4540
|
+
min,
|
|
4541
|
+
minutes,
|
|
4542
|
+
multiply,
|
|
4543
|
+
ok,
|
|
4544
|
+
once,
|
|
4545
|
+
orElse,
|
|
4546
|
+
orElseAsync,
|
|
4547
|
+
orElseValue,
|
|
4548
|
+
parse,
|
|
4549
|
+
partition,
|
|
4550
|
+
rateLimiterPresets,
|
|
4551
|
+
recover,
|
|
4552
|
+
recoverAsync,
|
|
4553
|
+
retry,
|
|
4554
|
+
retryPolicies,
|
|
4555
|
+
retryPolicy,
|
|
4556
|
+
run,
|
|
4557
|
+
runOrNull,
|
|
4558
|
+
runOrThrow,
|
|
4559
|
+
runOrThrowAsync,
|
|
4560
|
+
runOrUndefined,
|
|
4561
|
+
seconds,
|
|
4562
|
+
serialize,
|
|
4563
|
+
servicePolicies,
|
|
4564
|
+
singleflight,
|
|
4565
|
+
slugCategory,
|
|
4566
|
+
slugDocsUrl,
|
|
4567
|
+
stepOptions,
|
|
4568
|
+
subtract,
|
|
4569
|
+
tags,
|
|
4570
|
+
tap,
|
|
4571
|
+
tapError,
|
|
4572
|
+
timeout,
|
|
4573
|
+
timeoutPolicies,
|
|
4574
|
+
timeoutPolicy,
|
|
4575
|
+
toDays,
|
|
4576
|
+
toHours,
|
|
4577
|
+
toMillis,
|
|
4578
|
+
toMinutes,
|
|
4579
|
+
toSeconds,
|
|
4580
|
+
tryAsync,
|
|
4581
|
+
unless,
|
|
4582
|
+
unlessOr,
|
|
4583
|
+
unwrap,
|
|
4584
|
+
unwrapOr,
|
|
4585
|
+
unwrapOrElse,
|
|
4586
|
+
when,
|
|
4587
|
+
whenOr,
|
|
4588
|
+
withDeps,
|
|
4589
|
+
withPolicies,
|
|
4590
|
+
withPolicy,
|
|
4591
|
+
zero,
|
|
4592
|
+
zip,
|
|
4593
|
+
zipAsync
|
|
4594
|
+
});
|
|
2
4595
|
//# sourceMappingURL=index.cjs.map
|