@jagreehal/workflow 1.0.0 → 1.1.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/core.d.ts CHANGED
@@ -288,6 +288,42 @@ interface RunStep<E = unknown> {
288
288
  name?: string;
289
289
  key?: string;
290
290
  }) => Promise<T>;
291
+ /**
292
+ * Execute a Result-returning function and map its error to a typed error.
293
+ *
294
+ * Use this when calling functions that return Result<T, E> and you want to
295
+ * map their typed errors to your workflow's error type. Unlike step.try(),
296
+ * the error passed to onError is typed (not unknown).
297
+ *
298
+ * @param operation - A function that returns a Result or AsyncResult
299
+ * @param options - Configuration including error mapping
300
+ * @returns The success value (unwrapped)
301
+ * @throws {EarlyExit} If the result is an error (stops execution safely)
302
+ *
303
+ * @example
304
+ * ```typescript
305
+ * const response = await step.fromResult(
306
+ * () => callProvider(input),
307
+ * {
308
+ * name: "call-provider",
309
+ * onError: (providerError) => ({
310
+ * type: "PROVIDER_FAILED",
311
+ * provider: providerError.provider,
312
+ * cause: providerError
313
+ * })
314
+ * }
315
+ * );
316
+ * ```
317
+ */
318
+ fromResult: <T, ResultE, const Err extends E>(operation: () => Result<T, ResultE, unknown> | AsyncResult<T, ResultE, unknown>, options: {
319
+ error: Err;
320
+ name?: string;
321
+ key?: string;
322
+ } | {
323
+ onError: (resultError: ResultE) => Err;
324
+ name?: string;
325
+ key?: string;
326
+ }) => Promise<T>;
291
327
  }
292
328
  /**
293
329
  * Unified event stream for workflow execution.
@@ -440,6 +476,40 @@ declare function createEarlyExit<E>(error: E, meta: StepFailureMeta): EarlyExit<
440
476
  * @internal
441
477
  */
442
478
  declare function isEarlyExit<E>(e: unknown): e is EarlyExit<E>;
479
+ /**
480
+ * Execute a workflow with step-based error handling.
481
+ *
482
+ * ## When to Use run()
483
+ *
484
+ * Use `run()` when:
485
+ * - Dependencies are dynamic (passed at runtime, not known at compile time)
486
+ * - You don't need step caching or resume state
487
+ * - Error types are known upfront and can be specified manually
488
+ * - Building lightweight, one-off workflows
489
+ *
490
+ * For automatic error type inference from static dependencies, use `createWorkflow()`.
491
+ *
492
+ * ## Modes
493
+ *
494
+ * `run()` has three modes based on options:
495
+ * - **Strict Mode** (`catchUnexpected`): Returns `Result<T, E>` (closed union)
496
+ * - **Typed Mode** (`onError`): Returns `Result<T, E | UnexpectedError>`
497
+ * - **Safe Default** (no options): Returns `Result<T, UnexpectedError>`
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * // Typed mode with explicit error union
502
+ * const result = await run<Output, 'NOT_FOUND' | 'FETCH_ERROR'>(
503
+ * async (step) => {
504
+ * const user = await step(fetchUser(userId));
505
+ * return user;
506
+ * },
507
+ * { onError: (e) => console.log('Failed:', e) }
508
+ * );
509
+ * ```
510
+ *
511
+ * @see createWorkflow - For static dependencies with auto error inference
512
+ */
443
513
  /**
444
514
  * Execute a workflow with "Strict Mode" error handling.
445
515
  *
package/dist/core.js CHANGED
@@ -1,2 +1,2 @@
1
- var y=e=>({ok:!0,value:e}),s=(e,n)=>({ok:!1,error:e,...n?.cause!==void 0?{cause:n.cause}:{}}),W=e=>e.ok,Y=e=>!e.ok,N=e=>typeof e=="object"&&e!==null&&e.type==="UNEXPECTED_ERROR",b=Symbol("early-exit");function V(e,n){return{[b]:!0,error:e,meta:n}}function D(e){return typeof e=="object"&&e!==null&&e[b]===!0}var I=Symbol("mapper-exception");function j(e){return{[I]:!0,thrown:e}}function L(e){return typeof e=="object"&&e!==null&&e[I]===!0}function X(e){return typeof e=="string"?{name:e}:e??{}}async function _(e,n){let{onError:r,onEvent:o,catchUnexpected:u,workflowId:T,context:k}=n&&typeof n=="object"?n:{},a=T??crypto.randomUUID(),O=!r&&!u,E=t=>{o?.(t,k)},P=V,h=t=>D(t),S=(t,R)=>O?R?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:t,...R.resultCause!==void 0?{cause:R.resultCause}:{}}}:R?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:t,thrown:R.thrown}}:{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:t}}:t,M=t=>t.origin==="result"?t.resultCause:t.thrown,K=t=>({type:"UNEXPECTED_ERROR",cause:t.meta.origin==="result"?{type:"STEP_FAILURE",origin:"result",error:t.error,...t.meta.resultCause!==void 0?{cause:t.meta.resultCause}:{}}:{type:"STEP_FAILURE",origin:"throw",error:t.error,thrown:t.meta.thrown}});try{let t=(m,x)=>(async()=>{let{name:l,key:i}=X(x),v=o?performance.now():0;o&&E({type:"step_start",workflowId:a,stepKey:i,name:l,ts:Date.now()});let c;try{c=await(typeof m=="function"?m():m)}catch(w){let A=performance.now()-v;if(h(w))throw E({type:"step_aborted",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:A}),w;if(u){let C;try{C=u(w)}catch(F){throw j(F)}throw E({type:"step_error",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:A,error:C}),i&&E({type:"step_complete",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:A,result:s(C,{cause:w}),meta:{origin:"throw",thrown:w}}),r?.(C,l),P(C,{origin:"throw",thrown:w})}else{let C={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:w}};throw E({type:"step_error",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:A,error:C}),i&&E({type:"step_complete",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:A,result:s(C,{cause:w}),meta:{origin:"throw",thrown:w}}),w}}let p=performance.now()-v;if(c.ok)return E({type:"step_success",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:p}),i&&E({type:"step_complete",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:p,result:c}),c.value;let d=S(c.error,{origin:"result",resultCause:c.cause});throw E({type:"step_error",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:p,error:d}),i&&E({type:"step_complete",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:p,result:c,meta:{origin:"result",resultCause:c.cause}}),r?.(c.error,l),P(c.error,{origin:"result",resultCause:c.cause})})();t.try=(m,x)=>{let l=x.name,i=x.key,U="error"in x?()=>x.error:x.onError,v=o;return(async()=>{let c=v?performance.now():0;o&&E({type:"step_start",workflowId:a,stepKey:i,name:l,ts:Date.now()});try{let p=await m(),d=performance.now()-c;return E({type:"step_success",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:d}),i&&E({type:"step_complete",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:d,result:y(p)}),p}catch(p){let d=U(p),w=performance.now()-c,A=S(d,{origin:"throw",thrown:p});throw E({type:"step_error",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:w,error:A}),i&&E({type:"step_complete",workflowId:a,stepKey:i,name:l,ts:Date.now(),durationMs:w,result:s(d,{cause:p}),meta:{origin:"throw",thrown:p}}),r?.(d,l),P(d,{origin:"throw",thrown:p})}})()};let f=await e(t);return y(f)}catch(t){if(L(t))throw t.thrown;if(h(t)){let f=M(t.meta);if(u||r)return s(t.error,{cause:f});if(N(t.error))return s(t.error,{cause:f});let m=K(t);return s(m,{cause:f})}if(u){let f=u(t);return r?.(f,"unexpected"),s(f,{cause:t})}let R={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:t}};return r?.(R,"unexpected"),s(R,{cause:t})}}_.strict=(e,n)=>_(e,n);var g=class extends Error{constructor(r,o){super(`Unwrap called on an error result: ${String(r)}`);this.error=r;this.cause=o;this.name="UnwrapError"}},J=e=>{if(e.ok)return e.value;throw new g(e.error,e.cause)},G=(e,n)=>e.ok?e.value:n,q=(e,n)=>e.ok?e.value:n(e.error,e.cause);function B(e,n){try{return y(e())}catch(r){return n?s(n(r),{cause:r}):s(r)}}async function H(e,n){try{return y(await e)}catch(r){return n?s(n(r),{cause:r}):s(r)}}async function $(e,n){try{return y(await e())}catch(r){return n?s(n(r),{cause:r}):s(r)}}function z(e,n){return e!=null?y(e):s(n())}function Q(e,n){return e.ok?y(n(e.value)):e}function Z(e,n){return e.ok?e:s(n(e.error),{cause:e.cause})}function ee(e,n){return e.ok?n.ok(e.value):n.err(e.error,e.cause)}function ne(e,n){return e.ok?n(e.value):e}function re(e,n){return e.ok&&n(e.value),e}function te(e,n){return e.ok||n(e.error,e.cause),e}function oe(e,n,r){if(!e.ok)return e;try{return y(n(e.value))}catch(o){return s(r(o),{cause:o})}}function se(e,n,r){if(e.ok)return e;try{return s(n(e.error),{cause:e.cause})}catch(o){return s(r(o),{cause:o})}}function ue(e){let n=[];for(let r of e){if(!r.ok)return r;n.push(r.value)}return y(n)}async function ae(e){return e.length===0?y([]):new Promise(n=>{let r=!1,o=e.length,u=new Array(e.length);for(let T=0;T<e.length;T++){let k=T;Promise.resolve(e[k]).catch(a=>s({type:"PROMISE_REJECTED",cause:a},{cause:{type:"PROMISE_REJECTION",reason:a}})).then(a=>{if(!r){if(!a.ok){r=!0,n(a);return}u[k]=a.value,o--,o===0&&n(y(u))}})}})}function ie(e){let n=[],r=[];for(let o of e)o.ok?n.push(o.value):r.push({error:o.error,cause:o.cause});return r.length>0?s(r):y(n)}function le(e){let n=[],r=[];for(let o of e)o.ok?n.push(o.value):r.push(o.error);return{values:n,errors:r}}function Ee(e){if(e.length===0)return s({type:"EMPTY_INPUT",message:"any() requires at least one Result"});let n=null;for(let r of e){if(r.ok)return r;n||(n=r)}return n}async function ce(e){return e.length===0?s({type:"EMPTY_INPUT",message:"anyAsync() requires at least one Result"}):new Promise(n=>{let r=!1,o=e.length,u=null;for(let T of e)Promise.resolve(T).catch(k=>s({type:"PROMISE_REJECTED",cause:k},{cause:{type:"PROMISE_REJECTION",reason:k}})).then(k=>{if(!r){if(k.ok){r=!0,n(k);return}u||(u=k),o--,o===0&&n(u)}})})}async function pe(e){let n=await Promise.all(e.map(u=>Promise.resolve(u).then(T=>({status:"result",result:T})).catch(T=>({status:"rejected",error:{type:"PROMISE_REJECTED",cause:T},cause:{type:"PROMISE_REJECTION",reason:T}})))),r=[],o=[];for(let u of n)u.status==="rejected"?o.push({error:u.error,cause:u.cause}):u.result.ok?r.push(u.result.value):o.push({error:u.result.error,cause:u.result.cause});return o.length>0?s(o):y(r)}export{b as EARLY_EXIT_SYMBOL,g as UnwrapError,ue as all,ae as allAsync,ie as allSettled,pe as allSettledAsync,ne as andThen,Ee as any,ce as anyAsync,V as createEarlyExit,s as err,B as from,z as fromNullable,H as fromPromise,D as isEarlyExit,Y as isErr,W as isOk,N as isUnexpectedError,Q as map,Z as mapError,se as mapErrorTry,oe as mapTry,ee as match,y as ok,le as partition,_ as run,re as tap,te as tapError,$ as tryAsync,J as unwrap,G as unwrapOr,q as unwrapOrElse};
1
+ var k=e=>({ok:!0,value:e}),i=(e,n)=>({ok:!1,error:e,...n?.cause!==void 0?{cause:n.cause}:{}}),W=e=>e.ok,Y=e=>!e.ok,D=e=>typeof e=="object"&&e!==null&&e.type==="UNEXPECTED_ERROR",b=Symbol("early-exit");function N(e,n){return{[b]:!0,error:e,meta:n}}function V(e){return typeof e=="object"&&e!==null&&e[b]===!0}var I=Symbol("mapper-exception");function j(e){return{[I]:!0,thrown:e}}function L(e){return typeof e=="object"&&e!==null&&e[I]===!0}function X(e){return typeof e=="string"?{name:e}:e??{}}async function _(e,n){let{onError:r,onEvent:o,catchUnexpected:l,workflowId:R,context:d}=n&&typeof n=="object"?n:{},u=R??crypto.randomUUID(),O=!r&&!l,c=t=>{o?.(t,d)},P=N,U=t=>V(t),h=(t,f)=>O?f?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:t,...f.resultCause!==void 0?{cause:f.resultCause}:{}}}:f?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:t,thrown:f.thrown}}:{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:t}}:t,M=t=>t.origin==="result"?t.resultCause:t.thrown,K=t=>({type:"UNEXPECTED_ERROR",cause:t.meta.origin==="result"?{type:"STEP_FAILURE",origin:"result",error:t.error,...t.meta.resultCause!==void 0?{cause:t.meta.resultCause}:{}}:{type:"STEP_FAILURE",origin:"throw",error:t.error,thrown:t.meta.thrown}});try{let t=(m,T)=>(async()=>{let{name:a,key:s}=X(T),v=o?performance.now():0;o&&c({type:"step_start",workflowId:u,stepKey:s,name:a,ts:Date.now()});let p;try{p=await(typeof m=="function"?m():m)}catch(y){let C=performance.now()-v;if(U(y))throw c({type:"step_aborted",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:C}),y;if(l){let A;try{A=l(y)}catch(F){throw j(F)}throw c({type:"step_error",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:C,error:A}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:C,result:i(A,{cause:y}),meta:{origin:"throw",thrown:y}}),r?.(A,a),P(A,{origin:"throw",thrown:y})}else{let A={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:y}};throw c({type:"step_error",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:C,error:A}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:C,result:i(A,{cause:y}),meta:{origin:"throw",thrown:y}}),y}}let E=performance.now()-v;if(p.ok)return c({type:"step_success",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:E}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:E,result:p}),p.value;let w=h(p.error,{origin:"result",resultCause:p.cause});throw c({type:"step_error",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:E,error:w}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:E,result:p,meta:{origin:"result",resultCause:p.cause}}),r?.(p.error,a),P(p.error,{origin:"result",resultCause:p.cause})})();t.try=(m,T)=>{let a=T.name,s=T.key,g="error"in T?()=>T.error:T.onError,v=o;return(async()=>{let p=v?performance.now():0;o&&c({type:"step_start",workflowId:u,stepKey:s,name:a,ts:Date.now()});try{let E=await m(),w=performance.now()-p;return c({type:"step_success",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:w}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:w,result:k(E)}),E}catch(E){let w=g(E),y=performance.now()-p,C=h(w,{origin:"throw",thrown:E});throw c({type:"step_error",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:y,error:C}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:y,result:i(w,{cause:E}),meta:{origin:"throw",thrown:E}}),r?.(w,a),P(w,{origin:"throw",thrown:E})}})()},t.fromResult=(m,T)=>{let a=T.name,s=T.key,g="error"in T?()=>T.error:T.onError,v=o;return(async()=>{let p=v?performance.now():0;o&&c({type:"step_start",workflowId:u,stepKey:s,name:a,ts:Date.now()});let E=await m();if(E.ok){let w=performance.now()-p;return c({type:"step_success",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:w}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:w,result:k(E.value)}),E.value}else{let w=g(E.error),y=performance.now()-p,C=h(w,{origin:"result",resultCause:E.error});throw c({type:"step_error",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:y,error:C}),s&&c({type:"step_complete",workflowId:u,stepKey:s,name:a,ts:Date.now(),durationMs:y,result:i(w,{cause:E.error}),meta:{origin:"result",resultCause:E.error}}),r?.(w,a),P(w,{origin:"result",resultCause:E.error})}})()};let x=await e(t);return k(x)}catch(t){if(L(t))throw t.thrown;if(U(t)){let x=M(t.meta);if(l||r)return i(t.error,{cause:x});if(D(t.error))return i(t.error,{cause:x});let m=K(t);return i(m,{cause:x})}if(l){let x=l(t);return r?.(x,"unexpected"),i(x,{cause:t})}let f={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:t}};return r?.(f,"unexpected"),i(f,{cause:t})}}_.strict=(e,n)=>_(e,n);var S=class extends Error{constructor(r,o){super(`Unwrap called on an error result: ${String(r)}`);this.error=r;this.cause=o;this.name="UnwrapError"}},J=e=>{if(e.ok)return e.value;throw new S(e.error,e.cause)},G=(e,n)=>e.ok?e.value:n,q=(e,n)=>e.ok?e.value:n(e.error,e.cause);function B(e,n){try{return k(e())}catch(r){return n?i(n(r),{cause:r}):i(r)}}async function H(e,n){try{return k(await e)}catch(r){return n?i(n(r),{cause:r}):i(r)}}async function $(e,n){try{return k(await e())}catch(r){return n?i(n(r),{cause:r}):i(r)}}function z(e,n){return e!=null?k(e):i(n())}function Q(e,n){return e.ok?k(n(e.value)):e}function Z(e,n){return e.ok?e:i(n(e.error),{cause:e.cause})}function ee(e,n){return e.ok?n.ok(e.value):n.err(e.error,e.cause)}function ne(e,n){return e.ok?n(e.value):e}function re(e,n){return e.ok&&n(e.value),e}function te(e,n){return e.ok||n(e.error,e.cause),e}function oe(e,n,r){if(!e.ok)return e;try{return k(n(e.value))}catch(o){return i(r(o),{cause:o})}}function se(e,n,r){if(e.ok)return e;try{return i(n(e.error),{cause:e.cause})}catch(o){return i(r(o),{cause:o})}}function ue(e){let n=[];for(let r of e){if(!r.ok)return r;n.push(r.value)}return k(n)}async function ae(e){return e.length===0?k([]):new Promise(n=>{let r=!1,o=e.length,l=new Array(e.length);for(let R=0;R<e.length;R++){let d=R;Promise.resolve(e[d]).catch(u=>i({type:"PROMISE_REJECTED",cause:u},{cause:{type:"PROMISE_REJECTION",reason:u}})).then(u=>{if(!r){if(!u.ok){r=!0,n(u);return}l[d]=u.value,o--,o===0&&n(k(l))}})}})}function ie(e){let n=[],r=[];for(let o of e)o.ok?n.push(o.value):r.push({error:o.error,cause:o.cause});return r.length>0?i(r):k(n)}function le(e){let n=[],r=[];for(let o of e)o.ok?n.push(o.value):r.push(o.error);return{values:n,errors:r}}function Ee(e){if(e.length===0)return i({type:"EMPTY_INPUT",message:"any() requires at least one Result"});let n=null;for(let r of e){if(r.ok)return r;n||(n=r)}return n}async function ce(e){return e.length===0?i({type:"EMPTY_INPUT",message:"anyAsync() requires at least one Result"}):new Promise(n=>{let r=!1,o=e.length,l=null;for(let R of e)Promise.resolve(R).catch(d=>i({type:"PROMISE_REJECTED",cause:d},{cause:{type:"PROMISE_REJECTION",reason:d}})).then(d=>{if(!r){if(d.ok){r=!0,n(d);return}l||(l=d),o--,o===0&&n(l)}})})}async function pe(e){let n=await Promise.all(e.map(l=>Promise.resolve(l).then(R=>({status:"result",result:R})).catch(R=>({status:"rejected",error:{type:"PROMISE_REJECTED",cause:R},cause:{type:"PROMISE_REJECTION",reason:R}})))),r=[],o=[];for(let l of n)l.status==="rejected"?o.push({error:l.error,cause:l.cause}):l.result.ok?r.push(l.result.value):o.push({error:l.result.error,cause:l.result.cause});return o.length>0?i(o):k(r)}export{b as EARLY_EXIT_SYMBOL,S as UnwrapError,ue as all,ae as allAsync,ie as allSettled,pe as allSettledAsync,ne as andThen,Ee as any,ce as anyAsync,N as createEarlyExit,i as err,B as from,z as fromNullable,H as fromPromise,V as isEarlyExit,Y as isErr,W as isOk,D as isUnexpectedError,Q as map,Z as mapError,se as mapErrorTry,oe as mapTry,ee as match,k as ok,le as partition,_ as run,re as tap,te as tapError,$ as tryAsync,J as unwrap,G as unwrapOr,q as unwrapOrElse};
2
2
  //# sourceMappingURL=core.js.map