@jagreehal/workflow 1.3.0 → 1.5.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/README.md +138 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +215 -1
- package/dist/core.d.ts +215 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +9 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3266 -2
- package/dist/index.d.ts +3266 -2
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/visualize.cjs +6 -6
- package/dist/visualize.cjs.map +1 -1
- package/dist/visualize.d.cts +6 -0
- package/dist/visualize.d.ts +6 -0
- package/dist/visualize.js +6 -6
- package/dist/visualize.js.map +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.js +1 -1
- package/dist/workflow.js.map +1 -1
- package/docs/advanced.md +895 -0
- package/docs/api.md +257 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -280,9 +280,18 @@ if (result.ok) {
|
|
|
280
280
|
| `step(op())` | Unwrap Result or exit early |
|
|
281
281
|
| `step.try(fn, { error })` | Catch throws/rejects → typed error |
|
|
282
282
|
| `step.fromResult(fn, { onError })` | Map Result errors with typed onError |
|
|
283
|
+
| `step.retry(fn, opts)` | Retry with backoff on failure |
|
|
284
|
+
| `step.withTimeout(fn, { ms })` | Timeout after specified duration |
|
|
283
285
|
| `ok(value)` / `err(error)` | Create Results |
|
|
284
286
|
| `map`, `andThen`, `match` | Transform Results |
|
|
285
287
|
| `allAsync`, `partition` | Batch operations |
|
|
288
|
+
| `isStepTimeoutError(e)` | Check if error is a timeout |
|
|
289
|
+
| `getStepTimeoutMeta(e)` | Get timeout metadata from error |
|
|
290
|
+
| `createCircuitBreaker(name, config)` | Create circuit breaker for step protection |
|
|
291
|
+
| `createSagaWorkflow(deps, opts)` | Create saga with auto-compensation |
|
|
292
|
+
| `createRateLimiter(name, config)` | Control step throughput |
|
|
293
|
+
| `createWebhookHandler(workflow, fn, config)` | Expose workflow as HTTP endpoint |
|
|
294
|
+
| `createWorkflowHarness(deps, opts)` | Create test harness for workflows |
|
|
286
295
|
|
|
287
296
|
### Choosing Between run() and createWorkflow()
|
|
288
297
|
|
|
@@ -347,6 +356,84 @@ const result = await workflow(async (step) => {
|
|
|
347
356
|
});
|
|
348
357
|
```
|
|
349
358
|
|
|
359
|
+
### Retry with backoff
|
|
360
|
+
|
|
361
|
+
Automatically retry failed steps with configurable backoff:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
const result = await workflow(async (step) => {
|
|
365
|
+
// Retry up to 3 times with exponential backoff
|
|
366
|
+
const data = await step.retry(
|
|
367
|
+
() => fetchData(),
|
|
368
|
+
{
|
|
369
|
+
attempts: 3,
|
|
370
|
+
backoff: 'exponential', // 'fixed' | 'linear' | 'exponential'
|
|
371
|
+
initialDelay: 100, // ms
|
|
372
|
+
maxDelay: 5000, // cap delay at 5s
|
|
373
|
+
jitter: true, // add randomness to prevent thundering herd
|
|
374
|
+
retryOn: (error) => error !== 'FATAL', // custom retry predicate
|
|
375
|
+
}
|
|
376
|
+
);
|
|
377
|
+
return data;
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Or use retry options directly on `step()`:
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
const user = await step(() => fetchUser(id), {
|
|
385
|
+
key: 'user:1',
|
|
386
|
+
retry: { attempts: 3, backoff: 'exponential' },
|
|
387
|
+
});
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Timeout
|
|
391
|
+
|
|
392
|
+
Prevent steps from hanging with timeouts:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
const result = await workflow(async (step) => {
|
|
396
|
+
// Timeout after 5 seconds
|
|
397
|
+
const data = await step.withTimeout(
|
|
398
|
+
() => slowOperation(),
|
|
399
|
+
{ ms: 5000, name: 'slow-op' }
|
|
400
|
+
);
|
|
401
|
+
return data;
|
|
402
|
+
});
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
With AbortSignal for cancellable operations:
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
const data = await step.withTimeout(
|
|
409
|
+
(signal) => fetch('/api/data', { signal }),
|
|
410
|
+
{ ms: 5000, signal: true } // pass signal to operation
|
|
411
|
+
);
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Combine retry and timeout - each attempt gets its own timeout:
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
const data = await step.retry(
|
|
418
|
+
() => fetchData(),
|
|
419
|
+
{
|
|
420
|
+
attempts: 3,
|
|
421
|
+
timeout: { ms: 2000 }, // 2s timeout per attempt
|
|
422
|
+
}
|
|
423
|
+
);
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Detecting timeout errors:
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
import { isStepTimeoutError, getStepTimeoutMeta } from '@jagreehal/workflow';
|
|
430
|
+
|
|
431
|
+
if (!result.ok && isStepTimeoutError(result.error)) {
|
|
432
|
+
const meta = getStepTimeoutMeta(result.error);
|
|
433
|
+
console.log(`Timed out after ${meta?.timeoutMs}ms on attempt ${meta?.attempt}`);
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
350
437
|
### State save & resume
|
|
351
438
|
|
|
352
439
|
Save step results for workflow replay:
|
|
@@ -399,11 +486,48 @@ const workflow = createWorkflow({ fetchUser }, {
|
|
|
399
486
|
onEvent: (event) => {
|
|
400
487
|
// workflow_start | workflow_success | workflow_error
|
|
401
488
|
// step_start | step_success | step_error | step_complete
|
|
489
|
+
// step_retry | step_timeout | step_retries_exhausted
|
|
402
490
|
console.log(event.type, event.durationMs);
|
|
403
491
|
}
|
|
404
492
|
});
|
|
405
493
|
```
|
|
406
494
|
|
|
495
|
+
### Visualization
|
|
496
|
+
|
|
497
|
+
Render workflow execution as ASCII art or Mermaid diagrams:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
import { createIRBuilder, renderToAscii, renderToMermaid } from '@jagreehal/workflow/visualize';
|
|
501
|
+
|
|
502
|
+
const builder = createIRBuilder();
|
|
503
|
+
const workflow = createWorkflow({ fetchUser, fetchPosts }, {
|
|
504
|
+
onEvent: (event) => builder.addEvent(event),
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
await workflow(async (step) => {
|
|
508
|
+
const user = await step(() => fetchUser('1'), { name: 'Fetch user' });
|
|
509
|
+
const posts = await step(() => fetchPosts(user.id), { name: 'Fetch posts' });
|
|
510
|
+
return { user, posts };
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
// ASCII output
|
|
514
|
+
console.log(renderToAscii(builder.getIR()));
|
|
515
|
+
// ┌── my-workflow ──────────────────────────┐
|
|
516
|
+
// │ ✓ Fetch user [150ms] │
|
|
517
|
+
// │ ✓ Fetch posts [89ms] │
|
|
518
|
+
// │ Completed in 240ms │
|
|
519
|
+
// └─────────────────────────────────────────┘
|
|
520
|
+
|
|
521
|
+
// Mermaid output (for docs, GitHub, etc.)
|
|
522
|
+
console.log(renderToMermaid(builder.getIR()));
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Visualization includes retry and timeout indicators:
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
✓ Fetch data [500ms] [2 retries] [timeout 5000ms]
|
|
529
|
+
```
|
|
530
|
+
|
|
407
531
|
### Human-in-the-loop
|
|
408
532
|
|
|
409
533
|
```typescript
|
|
@@ -431,7 +555,20 @@ if (!result.ok && isPendingApproval(result.error)) {
|
|
|
431
555
|
|
|
432
556
|
### More utilities
|
|
433
557
|
|
|
434
|
-
See [docs/advanced.md](docs/advanced.md) for
|
|
558
|
+
See [docs/advanced.md](docs/advanced.md) for:
|
|
559
|
+
- Batch operations (`all`, `allSettled`, `partition`)
|
|
560
|
+
- Result transformers (`map`, `andThen`, `match`)
|
|
561
|
+
- Circuit breaker pattern
|
|
562
|
+
- Saga/compensation pattern for rollbacks
|
|
563
|
+
- Rate limiting and concurrency control
|
|
564
|
+
- Workflow versioning and migrations
|
|
565
|
+
- Pluggable persistence adapters
|
|
566
|
+
- Webhook and event trigger adapters
|
|
567
|
+
- Policy-driven step middleware
|
|
568
|
+
- Developer tools and visualization
|
|
569
|
+
- HITL orchestration helpers
|
|
570
|
+
- Deterministic testing harness
|
|
571
|
+
- OpenTelemetry integration
|
|
435
572
|
|
|
436
573
|
## API Reference
|
|
437
574
|
|
package/dist/core.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var b=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var G=Object.prototype.hasOwnProperty;var q=(e,n)=>{for(var t in n)b(e,t,{get:n[t],enumerable:!0})},B=(e,n,t,u)=>{if(n&&typeof n=="object"||typeof n=="function")for(let c of $(n))!G.call(e,c)&&c!==t&&b(e,c,{get:()=>n[c],enumerable:!(u=J(n,c))||u.enumerable});return e};var H=e=>B(b({},"__esModule",{value:!0}),e);var ge={};q(ge,{EARLY_EXIT_SYMBOL:()=>O,UnwrapError:()=>I,all:()=>de,allAsync:()=>Re,allSettled:()=>fe,allSettledAsync:()=>Ae,andThen:()=>Ee,any:()=>Ce,anyAsync:()=>xe,createEarlyExit:()=>F,err:()=>l,from:()=>se,fromNullable:()=>pe,fromPromise:()=>ue,isEarlyExit:()=>N,isErr:()=>Q,isOk:()=>z,isUnexpectedError:()=>D,map:()=>ie,mapError:()=>ce,mapErrorTry:()=>ke,mapTry:()=>Te,match:()=>le,ok:()=>f,partition:()=>me,run:()=>M,tap:()=>we,tapError:()=>ye,tryAsync:()=>ae,unwrap:()=>te,unwrapOr:()=>re,unwrapOrElse:()=>oe});module.exports=H(ge);var f=e=>({ok:!0,value:e}),l=(e,n)=>({ok:!1,error:e,...n?.cause!==void 0?{cause:n.cause}:{}}),z=e=>e.ok,Q=e=>!e.ok,D=e=>typeof e=="object"&&e!==null&&e.type==="UNEXPECTED_ERROR",O=Symbol("early-exit");function F(e,n){return{[O]:!0,error:e,meta:n}}function N(e){return typeof e=="object"&&e!==null&&e[O]===!0}var V=Symbol("mapper-exception");function Z(e){return{[V]:!0,thrown:e}}function ee(e){return typeof e=="object"&&e!==null&&e[V]===!0}function ne(e){return typeof e=="string"?{name:e}:e??{}}async function M(e,n){let{onError:t,onEvent:u,catchUnexpected:c,workflowId:C,context:A}=n&&typeof n=="object"?n:{},a=C??crypto.randomUUID(),j=!t&&!c,g=[],L=0,_=r=>r??`step_${++L}`,E=r=>{if(r.type==="step_success"){let S=r.stepId;for(let x=g.length-1;x>=0;x--){let T=g[x];if(T.type==="race"&&!T.winnerId){T.winnerId=S;break}}}u?.(r,A)},h=F,K=r=>N(r),U=(r,S)=>j?S?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r,...S.resultCause!==void 0?{cause:S.resultCause}:{}}}:S?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:r,thrown:S.thrown}}:{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r}}:r,X=r=>r.origin==="result"?r.resultCause:r.thrown,W=r=>({type:"UNEXPECTED_ERROR",cause:r.meta.origin==="result"?{type:"STEP_FAILURE",origin:"result",error:r.error,...r.meta.resultCause!==void 0?{cause:r.meta.resultCause}:{}}:{type:"STEP_FAILURE",origin:"throw",error:r.error,thrown:r.meta.thrown}});try{let r=(T,k)=>(async()=>{let{name:o,key:s}=ne(k),y=_(s),i=u?performance.now():0;u&&E({type:"step_start",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now()});let p;try{p=await(typeof T=="function"?T():T)}catch(R){let v=performance.now()-i;if(K(R))throw E({type:"step_aborted",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:v}),R;if(c){let P;try{P=c(R)}catch(Y){throw Z(Y)}throw E({type:"step_error",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:v,error:P}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:v,result:l(P,{cause:R}),meta:{origin:"throw",thrown:R}}),t?.(P,o),h(P,{origin:"throw",thrown:R})}else{let P={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:R}};throw E({type:"step_error",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:v,error:P}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:v,result:l(P,{cause:R}),meta:{origin:"throw",thrown:R}}),R}}let w=performance.now()-i;if(p.ok)return E({type:"step_success",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:w}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:w,result:p}),p.value;let d=U(p.error,{origin:"result",resultCause:p.cause});throw E({type:"step_error",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:w,error:d}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:w,result:p,meta:{origin:"result",resultCause:p.cause}}),t?.(p.error,o),h(p.error,{origin:"result",resultCause:p.cause})})();r.try=(T,k)=>{let o=k.name,s=k.key,y=_(s),m="error"in k?()=>k.error:k.onError,i=u;return(async()=>{let p=i?performance.now():0;u&&E({type:"step_start",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now()});try{let w=await T(),d=performance.now()-p;return E({type:"step_success",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:d}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:d,result:f(w)}),w}catch(w){let d=m(w),R=performance.now()-p,v=U(d,{origin:"throw",thrown:w});throw E({type:"step_error",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:R,error:v}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:R,result:l(d,{cause:w}),meta:{origin:"throw",thrown:w}}),t?.(d,o),h(d,{origin:"throw",thrown:w})}})()},r.fromResult=(T,k)=>{let o=k.name,s=k.key,y=_(s),m="error"in k?()=>k.error:k.onError,i=u;return(async()=>{let p=i?performance.now():0;u&&E({type:"step_start",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now()});let w=await T();if(w.ok){let d=performance.now()-p;return E({type:"step_success",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:d}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:d,result:f(w.value)}),w.value}else{let d=m(w.error),R=performance.now()-p,v=U(d,{origin:"result",resultCause:w.error});throw E({type:"step_error",workflowId:a,stepId:y,stepKey:s,name:o,ts:Date.now(),durationMs:R,error:v}),s&&E({type:"step_complete",workflowId:a,stepKey:s,name:o,ts:Date.now(),durationMs:R,result:l(d,{cause:w.error}),meta:{origin:"result",resultCause:w.error}}),t?.(d,o),h(d,{origin:"result",resultCause:w.error})}})()},r.parallel=(T,k)=>{let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),y=!1;g.push({scopeId:o,type:"parallel"});let m=()=>{if(y)return;y=!0;let i=g.findIndex(p=>p.scopeId===o);i!==-1&&g.splice(i,1),E({type:"scope_end",workflowId:a,scopeId:o,ts:Date.now(),durationMs:performance.now()-s})};E({type:"scope_start",workflowId:a,scopeId:o,scopeType:"parallel",name:T,ts:Date.now()});try{let i=await k();if(m(),!i.ok)throw t?.(i.error,T),h(i.error,{origin:"result",resultCause:i.cause});return i.value}catch(i){throw m(),i}})()},r.race=(T,k)=>{let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),y=!1,m={scopeId:o,type:"race",winnerId:void 0};g.push(m);let i=()=>{if(y)return;y=!0;let p=g.findIndex(w=>w.scopeId===o);p!==-1&&g.splice(p,1),E({type:"scope_end",workflowId:a,scopeId:o,ts:Date.now(),durationMs:performance.now()-s,winnerId:m.winnerId})};E({type:"scope_start",workflowId:a,scopeId:o,scopeType:"race",name:T,ts:Date.now()});try{let p=await k();if(i(),!p.ok)throw t?.(p.error,T),h(p.error,{origin:"result",resultCause:p.cause});return p.value}catch(p){throw i(),p}})()},r.allSettled=(T,k)=>{let o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),y=!1;g.push({scopeId:o,type:"allSettled"});let m=()=>{if(y)return;y=!0;let i=g.findIndex(p=>p.scopeId===o);i!==-1&&g.splice(i,1),E({type:"scope_end",workflowId:a,scopeId:o,ts:Date.now(),durationMs:performance.now()-s})};E({type:"scope_start",workflowId:a,scopeId:o,scopeType:"allSettled",name:T,ts:Date.now()});try{let i=await k();if(m(),!i.ok)throw t?.(i.error,T),h(i.error,{origin:"result",resultCause:i.cause});return i.value}catch(i){throw m(),i}})()};let x=await e(r);return f(x)}catch(r){if(ee(r))throw r.thrown;if(K(r)){let x=X(r.meta);if(c||t)return l(r.error,{cause:x});if(D(r.error))return l(r.error,{cause:x});let T=W(r);return l(T,{cause:x})}if(c){let x=c(r);return t?.(x,"unexpected"),l(x,{cause:r})}let S={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:r}};return t?.(S,"unexpected"),l(S,{cause:r})}}M.strict=(e,n)=>M(e,n);var I=class extends Error{constructor(t,u){super(`Unwrap called on an error result: ${String(t)}`);this.error=t;this.cause=u;this.name="UnwrapError"}},te=e=>{if(e.ok)return e.value;throw new I(e.error,e.cause)},re=(e,n)=>e.ok?e.value:n,oe=(e,n)=>e.ok?e.value:n(e.error,e.cause);function se(e,n){try{return f(e())}catch(t){return n?l(n(t),{cause:t}):l(t)}}async function ue(e,n){try{return f(await e)}catch(t){return n?l(n(t),{cause:t}):l(t)}}async function ae(e,n){try{return f(await e())}catch(t){return n?l(n(t),{cause:t}):l(t)}}function pe(e,n){return e!=null?f(e):l(n())}function ie(e,n){return e.ok?f(n(e.value)):e}function ce(e,n){return e.ok?e:l(n(e.error),{cause:e.cause})}function le(e,n){return e.ok?n.ok(e.value):n.err(e.error,e.cause)}function Ee(e,n){return e.ok?n(e.value):e}function we(e,n){return e.ok&&n(e.value),e}function ye(e,n){return e.ok||n(e.error,e.cause),e}function Te(e,n,t){if(!e.ok)return e;try{return f(n(e.value))}catch(u){return l(t(u),{cause:u})}}function ke(e,n,t){if(e.ok)return e;try{return l(n(e.error),{cause:e.cause})}catch(u){return l(t(u),{cause:u})}}function de(e){let n=[];for(let t of e){if(!t.ok)return t;n.push(t.value)}return f(n)}async function Re(e){return e.length===0?f([]):new Promise(n=>{let t=!1,u=e.length,c=new Array(e.length);for(let C=0;C<e.length;C++){let A=C;Promise.resolve(e[A]).catch(a=>l({type:"PROMISE_REJECTED",cause:a},{cause:{type:"PROMISE_REJECTION",reason:a}})).then(a=>{if(!t){if(!a.ok){t=!0,n(a);return}c[A]=a.value,u--,u===0&&n(f(c))}})}})}function fe(e){let n=[],t=[];for(let u of e)u.ok?n.push(u.value):t.push({error:u.error,cause:u.cause});return t.length>0?l(t):f(n)}function me(e){let n=[],t=[];for(let u of e)u.ok?n.push(u.value):t.push(u.error);return{values:n,errors:t}}function Ce(e){if(e.length===0)return l({type:"EMPTY_INPUT",message:"any() requires at least one Result"});let n=null;for(let t of e){if(t.ok)return t;n||(n=t)}return n}async function xe(e){return e.length===0?l({type:"EMPTY_INPUT",message:"anyAsync() requires at least one Result"}):new Promise(n=>{let t=!1,u=e.length,c=null;for(let C of e)Promise.resolve(C).catch(A=>l({type:"PROMISE_REJECTED",cause:A},{cause:{type:"PROMISE_REJECTION",reason:A}})).then(A=>{if(!t){if(A.ok){t=!0,n(A);return}c||(c=A),u--,u===0&&n(c)}})})}async function Ae(e){let n=await Promise.all(e.map(c=>Promise.resolve(c).then(C=>({status:"result",result:C})).catch(C=>({status:"rejected",error:{type:"PROMISE_REJECTED",cause:C},cause:{type:"PROMISE_REJECTION",reason:C}})))),t=[],u=[];for(let c of n)c.status==="rejected"?u.push({error:c.error,cause:c.cause}):c.result.ok?t.push(c.result.value):u.push({error:c.result.error,cause:c.result.cause});return u.length>0?l(u):f(t)}0&&(module.exports={EARLY_EXIT_SYMBOL,UnwrapError,all,allAsync,allSettled,allSettledAsync,andThen,any,anyAsync,createEarlyExit,err,from,fromNullable,fromPromise,isEarlyExit,isErr,isOk,isUnexpectedError,map,mapError,mapErrorTry,mapTry,match,ok,partition,run,tap,tapError,tryAsync,unwrap,unwrapOr,unwrapOrElse});
|
|
1
|
+
"use strict";var Y=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var ce=Object.prototype.hasOwnProperty;var Ee=(e,t)=>{for(var n in t)Y(e,n,{get:t[n],enumerable:!0})},ye=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let l of le(t))!ce.call(e,l)&&l!==n&&Y(e,l,{get:()=>t[l],enumerable:!(s=pe(t,l))||s.enumerable});return e};var me=e=>ye(Y({},"__esModule",{value:!0}),e);var Xe={};Ee(Xe,{EARLY_EXIT_SYMBOL:()=>G,STEP_TIMEOUT_MARKER:()=>O,UnwrapError:()=>N,all:()=>Ke,allAsync:()=>je,allSettled:()=>Fe,allSettledAsync:()=>We,andThen:()=>Me,any:()=>Ve,anyAsync:()=>Le,createEarlyExit:()=>ne,err:()=>T,from:()=>ge,fromNullable:()=>be,fromPromise:()=>Ae,getStepTimeoutMeta:()=>te,isEarlyExit:()=>re,isErr:()=>Te,isOk:()=>we,isStepTimeoutError:()=>J,isUnexpectedError:()=>ee,map:()=>he,mapError:()=>ve,mapErrorTry:()=>De,mapTry:()=>Ue,match:()=>_e,ok:()=>A,partition:()=>Ne,run:()=>$,tap:()=>Ie,tapError:()=>Oe,tryAsync:()=>Pe,unwrap:()=>Ce,unwrapOr:()=>xe,unwrapOrElse:()=>Se});module.exports=me(Xe);var A=e=>({ok:!0,value:e}),T=(e,t)=>({ok:!1,error:e,...t?.cause!==void 0?{cause:t.cause}:{}}),we=e=>e.ok,Te=e=>!e.ok,ee=e=>typeof e=="object"&&e!==null&&e.type==="UNEXPECTED_ERROR",O=Symbol.for("step_timeout_marker");function J(e){return typeof e!="object"||e===null?!1:e.type==="STEP_TIMEOUT"?!0:O in e}function te(e){if(!(typeof e!="object"||e===null)){if(e.type==="STEP_TIMEOUT"){let t=e;return{timeoutMs:t.timeoutMs,stepName:t.stepName,stepKey:t.stepKey,attempt:t.attempt}}if(O in e)return e[O]}}var G=Symbol("early-exit");function ne(e,t){return{[G]:!0,error:e,meta:t}}function re(e){return typeof e=="object"&&e!==null&&e[G]===!0}var oe=Symbol("mapper-exception");function ke(e){return{[oe]:!0,thrown:e}}function de(e){return typeof e=="object"&&e!==null&&e[oe]===!0}function fe(e){return typeof e=="string"?{name:e}:e??{}}function B(e,t){let{backoff:n,initialDelay:s,maxDelay:l,jitter:g}=t,k;switch(n){case"fixed":k=s;break;case"linear":k=s*e;break;case"exponential":k=s*Math.pow(2,e-1);break}if(k=Math.min(k,l),g){let o=k*.25*Math.random();k=k+o}return Math.floor(k)}function q(e){return new Promise(t=>setTimeout(t,e))}var Z=Symbol("timeout");async function Re(e,t,n){let s=new AbortController,l=t.error??{type:"STEP_TIMEOUT",stepName:n.name,stepKey:n.key,timeoutMs:t.ms,attempt:n.attempt},g,k=new Promise((v,x)=>{g=setTimeout(()=>{s.abort(),x({[Z]:!0,error:l})},t.ms)}),o;t.signal?o=Promise.resolve(e(s.signal)):o=Promise.resolve(e());try{return await Promise.race([o,k])}catch(v){if(typeof v=="object"&&v!==null&&v[Z]===!0){let x=v.error;if(typeof x=="object"&&x!==null&&x.type!=="STEP_TIMEOUT"){let K={timeoutMs:t.ms,stepName:n.name,stepKey:n.key,attempt:n.attempt};O in x?x[O]=K:Object.defineProperty(x,O,{value:K,enumerable:!1,writable:!0,configurable:!1})}throw x}throw v}finally{clearTimeout(g)}}var D={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,retryOn:()=>!0,onRetry:()=>{}};async function $(e,t){let{onError:n,onEvent:s,catchUnexpected:l,workflowId:g,context:k}=t&&typeof t=="object"?t:{},o=g??crypto.randomUUID(),v=!n&&!l,x=[],K=0,V=r=>r??`step_${++K}`,c=r=>{if(r.type==="step_success"){let h=r.stepId;for(let b=x.length-1;b>=0;b--){let w=x[b];if(w.type==="race"&&!w.winnerId){w.winnerId=h;break}}}s?.(r,k)},M=ne,H=r=>re(r),L=(r,h)=>v?h?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r,...h.resultCause!==void 0?{cause:h.resultCause}:{}}}:h?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:r,thrown:h.thrown}}:{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r}}:r,se=r=>r.origin==="result"?r.resultCause:r.thrown,ue=r=>({type:"UNEXPECTED_ERROR",cause:r.meta.origin==="result"?{type:"STEP_FAILURE",origin:"result",error:r.error,...r.meta.resultCause!==void 0?{cause:r.meta.resultCause}:{}}:{type:"STEP_FAILURE",origin:"throw",error:r.error,thrown:r.meta.thrown}});try{let r=(w,i)=>(async()=>{let m=fe(i),{name:u,key:a,retry:d,timeout:E}=m,p=V(a),f=s,R=f?performance.now():0;if(!(typeof w=="function")){if(d&&d.attempts>1)throw new Error("step: retry options require a function operation. Direct Promise/Result values cannot be re-executed on retry. Wrap your operation in a function: step(() => yourOperation, { retry: {...} })");if(E)throw new Error("step: timeout options require a function operation. Direct Promise/Result values cannot be wrapped with timeout after they've started. Wrap your operation in a function: step(() => yourOperation, { timeout: {...} })")}let S={attempts:Math.max(1,d?.attempts??1),backoff:d?.backoff??D.backoff,initialDelay:d?.initialDelay??D.initialDelay,maxDelay:d?.maxDelay??D.maxDelay,jitter:d?.jitter??D.jitter,retryOn:d?.retryOn??D.retryOn,onRetry:d?.onRetry??D.onRetry};s&&c({type:"step_start",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now()});let z;for(let C=1;C<=S.attempts;C++){let ie=f?performance.now():0;try{let y;if(typeof w=="function"?E?y=await Re(w,E,{name:u,key:a,attempt:C}):y=await w():y=await w,y.ok){let _=performance.now()-R;return c({type:"step_success",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:_}),a&&c({type:"step_complete",workflowId:o,stepKey:a,name:u,ts:Date.now(),durationMs:_,result:y}),y.value}if(z=y,C<S.attempts&&S.retryOn(y.error,C)){let _=B(C,S);c({type:"step_retry",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),attempt:C+1,maxAttempts:S.attempts,delayMs:_,error:y.error}),S.onRetry(y.error,C,_),await q(_);continue}S.attempts>1&&c({type:"step_retries_exhausted",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:C,lastError:y.error});break}catch(y){let _=performance.now()-ie;if(H(y))throw c({type:"step_aborted",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:_}),y;if(J(y)){let P=te(y),W=E?.ms??P?.timeoutMs??0;if(c({type:"step_timeout",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),timeoutMs:W,attempt:C}),C<S.attempts&&S.retryOn(y,C)){let X=B(C,S);c({type:"step_retry",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),attempt:C+1,maxAttempts:S.attempts,delayMs:X,error:y}),S.onRetry(y,C,X),await q(X);continue}S.attempts>1&&c({type:"step_retries_exhausted",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:C,lastError:y})}if(C<S.attempts&&S.retryOn(y,C)){let P=B(C,S);c({type:"step_retry",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),attempt:C+1,maxAttempts:S.attempts,delayMs:P,error:y}),S.onRetry(y,C,P),await q(P);continue}S.attempts>1&&!J(y)&&c({type:"step_retries_exhausted",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:C,lastError:y});let F=performance.now()-R;if(l){let P;try{P=l(y)}catch(W){throw ke(W)}throw c({type:"step_error",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:F,error:P}),a&&c({type:"step_complete",workflowId:o,stepKey:a,name:u,ts:Date.now(),durationMs:F,result:T(P,{cause:y}),meta:{origin:"throw",thrown:y}}),n?.(P,u),M(P,{origin:"throw",thrown:y})}else{let P={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:y}};throw c({type:"step_error",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:F,error:P}),a&&c({type:"step_complete",workflowId:o,stepKey:a,name:u,ts:Date.now(),durationMs:F,result:T(P,{cause:y}),meta:{origin:"throw",thrown:y}}),y}}}let I=z,Q=performance.now()-R,ae=L(I.error,{origin:"result",resultCause:I.cause});throw c({type:"step_error",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),durationMs:Q,error:ae}),a&&c({type:"step_complete",workflowId:o,stepKey:a,name:u,ts:Date.now(),durationMs:Q,result:I,meta:{origin:"result",resultCause:I.cause}}),n?.(I.error,u),M(I.error,{origin:"result",resultCause:I.cause})})();r.try=(w,i)=>{let m=i.name,u=i.key,a=V(u),d="error"in i?()=>i.error:i.onError,E=s;return(async()=>{let p=E?performance.now():0;s&&c({type:"step_start",workflowId:o,stepId:a,stepKey:u,name:m,ts:Date.now()});try{let f=await w(),R=performance.now()-p;return c({type:"step_success",workflowId:o,stepId:a,stepKey:u,name:m,ts:Date.now(),durationMs:R}),u&&c({type:"step_complete",workflowId:o,stepKey:u,name:m,ts:Date.now(),durationMs:R,result:A(f)}),f}catch(f){let R=d(f),U=performance.now()-p,j=L(R,{origin:"throw",thrown:f});throw c({type:"step_error",workflowId:o,stepId:a,stepKey:u,name:m,ts:Date.now(),durationMs:U,error:j}),u&&c({type:"step_complete",workflowId:o,stepKey:u,name:m,ts:Date.now(),durationMs:U,result:T(R,{cause:f}),meta:{origin:"throw",thrown:f}}),n?.(R,m),M(R,{origin:"throw",thrown:f})}})()},r.fromResult=(w,i)=>{let m=i.name,u=i.key,a=V(u),d="error"in i?()=>i.error:i.onError,E=s;return(async()=>{let p=E?performance.now():0;s&&c({type:"step_start",workflowId:o,stepId:a,stepKey:u,name:m,ts:Date.now()});let f=await w();if(f.ok){let R=performance.now()-p;return c({type:"step_success",workflowId:o,stepId:a,stepKey:u,name:m,ts:Date.now(),durationMs:R}),u&&c({type:"step_complete",workflowId:o,stepKey:u,name:m,ts:Date.now(),durationMs:R,result:A(f.value)}),f.value}else{let R=d(f.error),U=performance.now()-p,j=L(R,{origin:"result",resultCause:f.error});throw c({type:"step_error",workflowId:o,stepId:a,stepKey:u,name:m,ts:Date.now(),durationMs:U,error:j}),u&&c({type:"step_complete",workflowId:o,stepKey:u,name:m,ts:Date.now(),durationMs:U,result:T(R,{cause:f.error}),meta:{origin:"result",resultCause:f.error}}),n?.(R,m),M(R,{origin:"result",resultCause:f.error})}})()},r.retry=(w,i)=>r(w,{name:i.name,key:i.key,retry:{attempts:i.attempts,backoff:i.backoff,initialDelay:i.initialDelay,maxDelay:i.maxDelay,jitter:i.jitter,retryOn:i.retryOn,onRetry:i.onRetry},timeout:i.timeout}),r.withTimeout=(w,i)=>r(w,{name:i.name,key:i.key,timeout:i}),r.parallel=(w,i)=>{let m=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let u=performance.now(),a=!1;x.push({scopeId:m,type:"parallel"});let d=()=>{if(a)return;a=!0;let E=x.findIndex(p=>p.scopeId===m);E!==-1&&x.splice(E,1),c({type:"scope_end",workflowId:o,scopeId:m,ts:Date.now(),durationMs:performance.now()-u})};c({type:"scope_start",workflowId:o,scopeId:m,scopeType:"parallel",name:w,ts:Date.now()});try{let E=await i();if(d(),!E.ok)throw n?.(E.error,w),M(E.error,{origin:"result",resultCause:E.cause});return E.value}catch(E){throw d(),E}})()},r.race=(w,i)=>{let m=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let u=performance.now(),a=!1,d={scopeId:m,type:"race",winnerId:void 0};x.push(d);let E=()=>{if(a)return;a=!0;let p=x.findIndex(f=>f.scopeId===m);p!==-1&&x.splice(p,1),c({type:"scope_end",workflowId:o,scopeId:m,ts:Date.now(),durationMs:performance.now()-u,winnerId:d.winnerId})};c({type:"scope_start",workflowId:o,scopeId:m,scopeType:"race",name:w,ts:Date.now()});try{let p=await i();if(E(),!p.ok)throw n?.(p.error,w),M(p.error,{origin:"result",resultCause:p.cause});return p.value}catch(p){throw E(),p}})()},r.allSettled=(w,i)=>{let m=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let u=performance.now(),a=!1;x.push({scopeId:m,type:"allSettled"});let d=()=>{if(a)return;a=!0;let E=x.findIndex(p=>p.scopeId===m);E!==-1&&x.splice(E,1),c({type:"scope_end",workflowId:o,scopeId:m,ts:Date.now(),durationMs:performance.now()-u})};c({type:"scope_start",workflowId:o,scopeId:m,scopeType:"allSettled",name:w,ts:Date.now()});try{let E=await i();if(d(),!E.ok)throw n?.(E.error,w),M(E.error,{origin:"result",resultCause:E.cause});return E.value}catch(E){throw d(),E}})()};let b=await e(r);return A(b)}catch(r){if(de(r))throw r.thrown;if(H(r)){let b=se(r.meta);if(l||n)return T(r.error,{cause:b});if(ee(r.error))return T(r.error,{cause:b});let w=ue(r);return T(w,{cause:b})}if(l){let b=l(r);return n?.(b,"unexpected"),T(b,{cause:r})}let h={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:r}};return n?.(h,"unexpected"),T(h,{cause:r})}}$.strict=(e,t)=>$(e,t);var N=class extends Error{constructor(n,s){super(`Unwrap called on an error result: ${String(n)}`);this.error=n;this.cause=s;this.name="UnwrapError"}},Ce=e=>{if(e.ok)return e.value;throw new N(e.error,e.cause)},xe=(e,t)=>e.ok?e.value:t,Se=(e,t)=>e.ok?e.value:t(e.error,e.cause);function ge(e,t){try{return A(e())}catch(n){return t?T(t(n),{cause:n}):T(n)}}async function Ae(e,t){try{return A(await e)}catch(n){return t?T(t(n),{cause:n}):T(n)}}async function Pe(e,t){try{return A(await e())}catch(n){return t?T(t(n),{cause:n}):T(n)}}function be(e,t){return e!=null?A(e):T(t())}function he(e,t){return e.ok?A(t(e.value)):e}function ve(e,t){return e.ok?e:T(t(e.error),{cause:e.cause})}function _e(e,t){return e.ok?t.ok(e.value):t.err(e.error,e.cause)}function Me(e,t){return e.ok?t(e.value):e}function Ie(e,t){return e.ok&&t(e.value),e}function Oe(e,t){return e.ok||t(e.error,e.cause),e}function Ue(e,t,n){if(!e.ok)return e;try{return A(t(e.value))}catch(s){return T(n(s),{cause:s})}}function De(e,t,n){if(e.ok)return e;try{return T(t(e.error),{cause:e.cause})}catch(s){return T(n(s),{cause:s})}}function Ke(e){let t=[];for(let n of e){if(!n.ok)return n;t.push(n.value)}return A(t)}async function je(e){return e.length===0?A([]):new Promise(t=>{let n=!1,s=e.length,l=new Array(e.length);for(let g=0;g<e.length;g++){let k=g;Promise.resolve(e[k]).catch(o=>T({type:"PROMISE_REJECTED",cause:o},{cause:{type:"PROMISE_REJECTION",reason:o}})).then(o=>{if(!n){if(!o.ok){n=!0,t(o);return}l[k]=o.value,s--,s===0&&t(A(l))}})}})}function Fe(e){let t=[],n=[];for(let s of e)s.ok?t.push(s.value):n.push({error:s.error,cause:s.cause});return n.length>0?T(n):A(t)}function Ne(e){let t=[],n=[];for(let s of e)s.ok?t.push(s.value):n.push(s.error);return{values:t,errors:n}}function Ve(e){if(e.length===0)return T({type:"EMPTY_INPUT",message:"any() requires at least one Result"});let t=null;for(let n of e){if(n.ok)return n;t||(t=n)}return t}async function Le(e){return e.length===0?T({type:"EMPTY_INPUT",message:"anyAsync() requires at least one Result"}):new Promise(t=>{let n=!1,s=e.length,l=null;for(let g of e)Promise.resolve(g).catch(k=>T({type:"PROMISE_REJECTED",cause:k},{cause:{type:"PROMISE_REJECTION",reason:k}})).then(k=>{if(!n){if(k.ok){n=!0,t(k);return}l||(l=k),s--,s===0&&t(l)}})})}async function We(e){let t=await Promise.all(e.map(l=>Promise.resolve(l).then(g=>({status:"result",result:g})).catch(g=>({status:"rejected",error:{type:"PROMISE_REJECTED",cause:g},cause:{type:"PROMISE_REJECTION",reason:g}})))),n=[],s=[];for(let l of t)l.status==="rejected"?s.push({error:l.error,cause:l.cause}):l.result.ok?n.push(l.result.value):s.push({error:l.result.error,cause:l.result.cause});return s.length>0?T(s):A(n)}0&&(module.exports={EARLY_EXIT_SYMBOL,STEP_TIMEOUT_MARKER,UnwrapError,all,allAsync,allSettled,allSettledAsync,andThen,any,anyAsync,createEarlyExit,err,from,fromNullable,fromPromise,getStepTimeoutMeta,isEarlyExit,isErr,isOk,isStepTimeoutError,isUnexpectedError,map,mapError,mapErrorTry,mapTry,match,ok,partition,run,tap,tapError,tryAsync,unwrap,unwrapOr,unwrapOrElse});
|
|
2
2
|
//# sourceMappingURL=core.cjs.map
|