@jagreehal/workflow 1.6.0 → 1.7.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 CHANGED
@@ -154,6 +154,102 @@ const result = await processPayment(async (step) => {
154
154
  });
155
155
  ```
156
156
 
157
+ ### 💾 Save & Resume (Persist Workflows Across Restarts)
158
+
159
+ Save workflow state to a database and resume later from exactly where you left off. Perfect for long-running workflows, crash recovery, or pausing for approvals.
160
+
161
+ **Step 1: Collect state during execution**
162
+
163
+ ```typescript
164
+ import { createWorkflow, createStepCollector } from '@jagreehal/workflow';
165
+
166
+ // Create a collector to automatically capture step results
167
+ const collector = createStepCollector();
168
+
169
+ const workflow = createWorkflow({ fetchUser, fetchPosts }, {
170
+ onEvent: collector.handleEvent, // Automatically collects step_complete events
171
+ });
172
+
173
+ await workflow(async (step) => {
174
+ // Only steps with keys are saved
175
+ const user = await step(() => fetchUser("1"), { key: "user:1" });
176
+ const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` });
177
+ return { user, posts };
178
+ });
179
+
180
+ // Get the collected state
181
+ const state = collector.getState(); // Returns ResumeState
182
+ ```
183
+
184
+ **Step 2: Save to database**
185
+
186
+ ```typescript
187
+ import { stringifyState, parseState } from '@jagreehal/workflow';
188
+
189
+ // Serialize to JSON
190
+ const json = stringifyState(state, { workflowId: "123", timestamp: Date.now() });
191
+
192
+ // Save to your database
193
+ await db.workflowStates.create({
194
+ id: workflowId,
195
+ state: json,
196
+ createdAt: new Date(),
197
+ });
198
+ ```
199
+
200
+ **Step 3: Resume from saved state**
201
+
202
+ ```typescript
203
+ // Load from database
204
+ const saved = await db.workflowStates.findUnique({ where: { id: workflowId } });
205
+ const savedState = parseState(saved.state);
206
+
207
+ // Resume workflow - cached steps skip execution
208
+ const workflow = createWorkflow({ fetchUser, fetchPosts }, {
209
+ resumeState: savedState, // Pre-populates cache from saved state
210
+ });
211
+
212
+ await workflow(async (step) => {
213
+ const user = await step(() => fetchUser("1"), { key: "user:1" }); // ✅ Cache hit - no fetchUser call
214
+ const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` }); // ✅ Cache hit
215
+ return { user, posts };
216
+ });
217
+ ```
218
+
219
+ **With database adapter (Redis, DynamoDB, etc.)**
220
+
221
+ ```typescript
222
+ import { createStatePersistence } from '@jagreehal/workflow';
223
+ import { createClient } from 'redis';
224
+
225
+ const redis = createClient();
226
+ await redis.connect();
227
+
228
+ // Create persistence adapter
229
+ const persistence = createStatePersistence({
230
+ get: (key) => redis.get(key),
231
+ set: (key, value) => redis.set(key, value),
232
+ delete: (key) => redis.del(key).then(n => n > 0),
233
+ exists: (key) => redis.exists(key).then(n => n > 0),
234
+ keys: (pattern) => redis.keys(pattern),
235
+ }, 'workflow:state:');
236
+
237
+ // Save
238
+ await persistence.save(runId, state, { metadata: { userId: 'user-1' } });
239
+
240
+ // Load
241
+ const savedState = await persistence.load(runId);
242
+
243
+ // Resume
244
+ const workflow = createWorkflow(deps, { resumeState: savedState });
245
+ ```
246
+
247
+ **Key points:**
248
+ - Only steps with `key` options are saved (unkeyed steps execute fresh on resume)
249
+ - Error results are preserved with metadata for proper replay
250
+ - You can also pass an async function: `resumeState: async () => await loadFromDB()`
251
+ - Works seamlessly with HITL approvals and crash recovery
252
+
157
253
  ### 🧑‍💻 Human-in-the-Loop
158
254
 
159
255
  Pause for manual approvals (large transfers, deployments, refunds) and resume exactly where you left off.
@@ -281,6 +377,82 @@ That's the foundation. Now let's build on it.
281
377
 
282
378
  ---
283
379
 
380
+ ## Persistence Quickstart
381
+
382
+ Save workflow state to a database and resume later. Perfect for crash recovery, long-running workflows, or pausing for approvals.
383
+
384
+ ### Basic Save & Resume
385
+
386
+ ```typescript
387
+ import { createWorkflow, createStepCollector, stringifyState, parseState } from '@jagreehal/workflow';
388
+
389
+ // 1. Collect state during execution
390
+ const collector = createStepCollector();
391
+ const workflow = createWorkflow({ fetchUser, fetchPosts }, {
392
+ onEvent: collector.handleEvent,
393
+ });
394
+
395
+ await workflow(async (step) => {
396
+ const user = await step(() => fetchUser("1"), { key: "user:1" });
397
+ const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` });
398
+ return { user, posts };
399
+ });
400
+
401
+ // 2. Save to database
402
+ const state = collector.getState();
403
+ const json = stringifyState(state, { workflowId: "123" });
404
+ await db.workflowStates.create({ id: "123", state: json });
405
+
406
+ // 3. Resume later
407
+ const saved = await db.workflowStates.findUnique({ where: { id: "123" } });
408
+ const savedState = parseState(saved.state);
409
+
410
+ const resumed = createWorkflow({ fetchUser, fetchPosts }, {
411
+ resumeState: savedState,
412
+ });
413
+
414
+ // Cached steps skip execution automatically
415
+ await resumed(async (step) => {
416
+ const user = await step(() => fetchUser("1"), { key: "user:1" }); // ✅ Cache hit
417
+ const posts = await step(() => fetchPosts(user.id), { key: `posts:${user.id}` }); // ✅ Cache hit
418
+ return { user, posts };
419
+ });
420
+ ```
421
+
422
+ ### With Database Adapter (Redis, DynamoDB, etc.)
423
+
424
+ ```typescript
425
+ import { createStatePersistence } from '@jagreehal/workflow';
426
+ import { createClient } from 'redis';
427
+
428
+ const redis = createClient();
429
+ await redis.connect();
430
+
431
+ // Create persistence adapter
432
+ const persistence = createStatePersistence({
433
+ get: (key) => redis.get(key),
434
+ set: (key, value) => redis.set(key, value),
435
+ delete: (key) => redis.del(key).then(n => n > 0),
436
+ exists: (key) => redis.exists(key).then(n => n > 0),
437
+ keys: (pattern) => redis.keys(pattern),
438
+ }, 'workflow:state:');
439
+
440
+ // Save
441
+ const collector = createStepCollector();
442
+ const workflow = createWorkflow(deps, { onEvent: collector.handleEvent });
443
+ await workflow(async (step) => { /* ... */ });
444
+
445
+ await persistence.save('run-123', collector.getState(), { userId: 'user-1' });
446
+
447
+ // Load and resume
448
+ const savedState = await persistence.load('run-123');
449
+ const resumed = createWorkflow(deps, { resumeState: savedState });
450
+ ```
451
+
452
+ **See the [Save & Resume](#-save--resume-persist-workflows-across-restarts) section for more details.**
453
+
454
+ ---
455
+
284
456
  ## Guided Tutorial
285
457
 
286
458
  We'll take a single workflow through four stages - from basic to production-ready. Each stage builds on the last, so you'll see how features compose naturally.
@@ -356,29 +528,37 @@ Pause long-running workflows until an operator approves, then resume using persi
356
528
  import {
357
529
  createApprovalStep,
358
530
  createWorkflow,
531
+ createStepCollector,
359
532
  injectApproval,
360
533
  isPendingApproval,
361
- isStepComplete,
362
- type ResumeStateEntry,
363
534
  } from '@jagreehal/workflow';
364
535
 
365
- const savedSteps = new Map<string, ResumeStateEntry>();
536
+ // Use collector to automatically capture state
537
+ const collector = createStepCollector();
366
538
  const requireApproval = createApprovalStep({
367
539
  key: 'approval:deploy',
368
540
  checkApproval: async () => ({ status: 'pending' }),
369
541
  });
370
542
 
371
543
  const gatedWorkflow = createWorkflow({ requireApproval }, {
372
- onEvent: (event) => {
373
- if (isStepComplete(event)) savedSteps.set(event.stepKey, { result: event.result, meta: event.meta });
374
- },
544
+ onEvent: collector.handleEvent, // Automatically collects step results
375
545
  });
376
546
 
377
547
  const result = await gatedWorkflow(async (step) => step(requireApproval, { key: 'approval:deploy' }));
378
548
 
379
549
  if (!result.ok && isPendingApproval(result.error)) {
380
- // later
381
- injectApproval({ steps: savedSteps }, { stepKey: 'approval:deploy', value: { approvedBy: 'ops' } });
550
+ // Get collected state
551
+ const state = collector.getState();
552
+
553
+ // Later, when approval is granted, inject it and resume
554
+ const updatedState = injectApproval(state, {
555
+ stepKey: 'approval:deploy',
556
+ value: { approvedBy: 'ops' },
557
+ });
558
+
559
+ // Resume with approval injected
560
+ const resumed = createWorkflow({ requireApproval }, { resumeState: updatedState });
561
+ await resumed(async (step) => step(requireApproval, { key: 'approval:deploy' })); // Uses injected approval
382
562
  }
383
563
  ```
384
564
 
@@ -547,15 +727,24 @@ const result = await validateAndCheckout(async (step) => {
547
727
  - **State save & resume** – Persist step completions and resume later.
548
728
 
549
729
  ```typescript
550
- import { createWorkflow, isStepComplete, type ResumeStateEntry } from '@jagreehal/workflow';
730
+ import { createWorkflow, createStepCollector } from '@jagreehal/workflow';
551
731
 
552
- const savedSteps = new Map<string, ResumeStateEntry>();
732
+ // Collect state during execution
733
+ const collector = createStepCollector();
553
734
  const workflow = createWorkflow(deps, {
554
- onEvent: (event) => {
555
- if (isStepComplete(event)) savedSteps.set(event.stepKey, { result: event.result, meta: event.meta });
556
- },
735
+ onEvent: collector.handleEvent, // Automatically collects step_complete events
736
+ });
737
+
738
+ await workflow(async (step) => {
739
+ const user = await step(() => fetchUser("1"), { key: "user:1" });
740
+ return user;
557
741
  });
558
- const resumed = createWorkflow(deps, { resumeState: { steps: savedSteps } });
742
+
743
+ // Get collected state
744
+ const state = collector.getState();
745
+
746
+ // Resume later
747
+ const resumed = createWorkflow(deps, { resumeState: state });
559
748
  ```
560
749
 
561
750
  - **Human-in-the-loop approvals** – Pause a workflow until someone approves.
@@ -605,16 +794,25 @@ const result = await validateAndCheckout(async (step) => {
605
794
  const data = map(result, ([user, posts]) => ({ user, posts }));
606
795
  ```
607
796
 
608
- ## Real-World Example: Safe Payment Retries
797
+ ## Real-World Example: Safe Payment Retries with Persistence
609
798
 
610
799
  The scariest failure mode in payments: **charge succeeded, but persistence failed**. If you retry naively, you charge the customer twice.
611
800
 
612
- Step keys solve this. Once a step succeeds, it's cached - retries skip it automatically:
801
+ Step keys + persistence solve this. Save state to a database, and if the workflow crashes, resume from the last successful step:
613
802
 
614
803
  ```typescript
804
+ import { createWorkflow, createStepCollector, stringifyState, parseState } from '@jagreehal/workflow';
805
+
615
806
  const processPayment = createWorkflow({ validateCard, chargeProvider, persistResult });
616
807
 
617
- const result = await processPayment(async (step) => {
808
+ // Collect state for persistence
809
+ const collector = createStepCollector();
810
+ const workflow = createWorkflow(
811
+ { validateCard, chargeProvider, persistResult },
812
+ { onEvent: collector.handleEvent }
813
+ );
814
+
815
+ const result = await workflow(async (step) => {
618
816
  const card = await step(() => validateCard(input), { key: 'validate' });
619
817
 
620
818
  // This is the dangerous step. Once it succeeds, never repeat it:
@@ -622,15 +820,53 @@ const result = await processPayment(async (step) => {
622
820
  key: `charge:${input.idempotencyKey}`,
623
821
  });
624
822
 
625
- // If THIS fails (DB down), you can rerun the workflow later.
823
+ // If THIS fails (DB down), save state and rerun later.
626
824
  // The charge step is cached - it won't execute again.
627
825
  await step(() => persistResult(charge), { key: `persist:${charge.id}` });
628
826
 
629
827
  return { paymentId: charge.id };
630
828
  });
829
+
830
+ // Save state after each run (or on crash)
831
+ if (result.ok) {
832
+ const state = collector.getState();
833
+ const json = stringifyState(state, { orderId: input.orderId });
834
+ await db.workflowStates.upsert({
835
+ where: { idempotencyKey: input.idempotencyKey },
836
+ update: { state: json, updatedAt: new Date() },
837
+ create: { idempotencyKey: input.idempotencyKey, state: json },
838
+ });
839
+ }
840
+ ```
841
+
842
+ **Crash recovery:** If the workflow crashes after charging but before persisting:
843
+
844
+ ```typescript
845
+ // On restart, load saved state
846
+ const saved = await db.workflowStates.findUnique({
847
+ where: { idempotencyKey: input.idempotencyKey },
848
+ });
849
+
850
+ if (saved) {
851
+ const savedState = parseState(saved.state);
852
+ const workflow = createWorkflow(
853
+ { validateCard, chargeProvider, persistResult },
854
+ { resumeState: savedState }
855
+ );
856
+
857
+ // Resume - charge step uses cached result, no double-billing!
858
+ const result = await workflow(async (step) => {
859
+ const card = await step(() => validateCard(input), { key: 'validate' }); // Cache hit
860
+ const charge = await step(() => chargeProvider(card), {
861
+ key: `charge:${input.idempotencyKey}`,
862
+ }); // Cache hit - returns previous charge result
863
+ await step(() => persistResult(charge), { key: `persist:${charge.id}` }); // Executes fresh
864
+ return { paymentId: charge.id };
865
+ });
866
+ }
631
867
  ```
632
868
 
633
- Crash after charging but before persisting? Rerun the workflow. The charge step returns its cached result. No double-billing.
869
+ Crash after charging but before persisting? Resume the workflow. The charge step returns its cached result. No double-billing.
634
870
 
635
871
  ## Is This Library Right for You?
636
872
 
package/dist/core.cjs CHANGED
@@ -1,2 +1,2 @@
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 $e={};Ee($e,{EARLY_EXIT_SYMBOL:()=>G,STEP_TIMEOUT_MARKER:()=>O,UnwrapError:()=>N,all:()=>Le,allAsync:()=>We,allSettled:()=>Xe,allSettledAsync:()=>Je,andThen:()=>Me,any:()=>Be,anyAsync:()=>qe,bimap:()=>Ke,createEarlyExit:()=>ne,err:()=>T,from:()=>ge,fromNullable:()=>ve,fromPromise:()=>Ae,getStepTimeoutMeta:()=>te,isEarlyExit:()=>re,isErr:()=>Te,isOk:()=>we,isStepTimeoutError:()=>J,isUnexpectedError:()=>ee,map:()=>be,mapError:()=>he,mapErrorTry:()=>De,mapTry:()=>Ue,match:()=>_e,ok:()=>S,orElse:()=>Fe,orElseAsync:()=>je,partition:()=>Ye,recover:()=>Ne,recoverAsync:()=>Ve,run:()=>$,tap:()=>Ie,tapError:()=>Oe,tryAsync:()=>Pe,unwrap:()=>Ce,unwrapOr:()=>xe,unwrapOrElse:()=>Se});module.exports=me($e);var S=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:A}=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),A){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},A,k=new Promise((h,x)=>{A=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(h){if(typeof h=="object"&&h!==null&&h[Z]===!0){let x=h.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 h}finally{clearTimeout(A)}}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:A,context:k}=t&&typeof t=="object"?t:{},o=A??crypto.randomUUID(),h=!n&&!l,x=[],K=0,V=r=>r??`step_${++K}`,c=r=>{if(r.type==="step_success"){let b=r.stepId;for(let v=x.length-1;v>=0;v--){let w=x[v];if(w.type==="race"&&!w.winnerId){w.winnerId=b;break}}}s?.(r,k)},M=ne,H=r=>re(r),L=(r,b)=>h?b?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r,...b.resultCause!==void 0?{cause:b.resultCause}:{}}}:b?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:r,thrown:b.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 g={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<=g.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<g.attempts&&g.retryOn(y.error,C)){let _=B(C,g);c({type:"step_retry",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),attempt:C+1,maxAttempts:g.attempts,delayMs:_,error:y.error}),g.onRetry(y.error,C,_),await q(_);continue}g.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<g.attempts&&g.retryOn(y,C)){let X=B(C,g);c({type:"step_retry",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),attempt:C+1,maxAttempts:g.attempts,delayMs:X,error:y}),g.onRetry(y,C,X),await q(X);continue}g.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<g.attempts&&g.retryOn(y,C)){let P=B(C,g);c({type:"step_retry",workflowId:o,stepId:p,stepKey:a,name:u,ts:Date.now(),attempt:C+1,maxAttempts:g.attempts,delayMs:P,error:y}),g.onRetry(y,C,P),await q(P);continue}g.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 j=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:j,error:P}),a&&c({type:"step_complete",workflowId:o,stepKey:a,name:u,ts:Date.now(),durationMs:j,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:j,error:P}),a&&c({type:"step_complete",workflowId:o,stepKey:a,name:u,ts:Date.now(),durationMs:j,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:S(f)}),f}catch(f){let R=d(f),U=performance.now()-p,F=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:F}),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:S(f.value)}),f.value}else{let R=d(f.error),U=performance.now()-p,F=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:F}),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 v=await e(r);return S(v)}catch(r){if(de(r))throw r.thrown;if(H(r)){let v=se(r.meta);if(l||n)return T(r.error,{cause:v});if(ee(r.error))return T(r.error,{cause:v});let w=ue(r);return T(w,{cause:v})}if(l){let v=l(r);return n?.(v,"unexpected"),T(v,{cause:r})}let b={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:r}};return n?.(b,"unexpected"),T(b,{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 S(e())}catch(n){return t?T(t(n),{cause:n}):T(n)}}async function Ae(e,t){try{return S(await e)}catch(n){return t?T(t(n),{cause:n}):T(n)}}async function Pe(e,t){try{return S(await e())}catch(n){return t?T(t(n),{cause:n}):T(n)}}function ve(e,t){return e!=null?S(e):T(t())}function be(e,t){return e.ok?S(t(e.value)):e}function he(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 S(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,t,n){return e.ok?S(t(e.value)):T(n(e.error),{cause:e.cause})}function Fe(e,t){return e.ok?e:t(e.error,e.cause)}async function je(e,t){let n=await e;return n.ok?n:t(n.error,n.cause)}function Ne(e,t){return e.ok?S(e.value):S(t(e.error,e.cause))}async function Ve(e,t){let n=await e;return n.ok?S(n.value):S(await t(n.error,n.cause))}function Le(e){let t=[];for(let n of e){if(!n.ok)return n;t.push(n.value)}return S(t)}async function We(e){return e.length===0?S([]):new Promise(t=>{let n=!1,s=e.length,l=new Array(e.length);for(let A=0;A<e.length;A++){let k=A;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(S(l))}})}})}function Xe(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):S(t)}function Ye(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 Be(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 qe(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 A of e)Promise.resolve(A).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 Je(e){let t=await Promise.all(e.map(l=>Promise.resolve(l).then(A=>({status:"result",result:A})).catch(A=>({status:"rejected",error:{type:"PROMISE_REJECTED",cause:A},cause:{type:"PROMISE_REJECTION",reason:A}})))),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):S(n)}0&&(module.exports={EARLY_EXIT_SYMBOL,STEP_TIMEOUT_MARKER,UnwrapError,all,allAsync,allSettled,allSettledAsync,andThen,any,anyAsync,bimap,createEarlyExit,err,from,fromNullable,fromPromise,getStepTimeoutMeta,isEarlyExit,isErr,isOk,isStepTimeoutError,isUnexpectedError,map,mapError,mapErrorTry,mapTry,match,ok,orElse,orElseAsync,partition,recover,recoverAsync,run,tap,tapError,tryAsync,unwrap,unwrapOr,unwrapOrElse});
1
+ "use strict";var q=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var ye=Object.prototype.hasOwnProperty;var me=(e,t)=>{for(var n in t)q(e,n,{get:t[n],enumerable:!0})},we=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let y of Ee(t))!ye.call(e,y)&&y!==n&&q(e,y,{get:()=>t[y],enumerable:!(a=ce(t,y))||a.enumerable});return e};var Te=e=>we(q({},"__esModule",{value:!0}),e);var He={};me(He,{EARLY_EXIT_SYMBOL:()=>Z,STEP_TIMEOUT_MARKER:()=>D,UnwrapError:()=>W,all:()=>Xe,allAsync:()=>Ye,allSettled:()=>$e,allSettledAsync:()=>Ge,andThen:()=>Oe,any:()=>Be,anyAsync:()=>qe,bimap:()=>Fe,createEarlyExit:()=>oe,err:()=>d,from:()=>be,fromNullable:()=>_e,fromPromise:()=>Pe,getStepTimeoutMeta:()=>re,isEarlyExit:()=>se,isErr:()=>de,isOk:()=>ke,isStepTimeoutError:()=>z,isUnexpectedError:()=>ne,map:()=>ve,mapError:()=>Me,mapErrorTry:()=>je,mapTry:()=>Ke,match:()=>Ie,ok:()=>g,orElse:()=>Ne,orElseAsync:()=>Ve,partition:()=>Je,recover:()=>Le,recoverAsync:()=>We,run:()=>Q,tap:()=>Ue,tapError:()=>De,tryAsync:()=>he,unwrap:()=>Se,unwrapOr:()=>ge,unwrapOrElse:()=>Ae});module.exports=Te(He);var g=e=>({ok:!0,value:e}),d=(e,t)=>({ok:!1,error:e,...t?.cause!==void 0?{cause:t.cause}:{}}),ke=e=>e.ok,de=e=>!e.ok,ne=e=>typeof e=="object"&&e!==null&&e.type==="UNEXPECTED_ERROR",D=Symbol.for("step_timeout_marker");function z(e){return typeof e!="object"||e===null?!1:e.type==="STEP_TIMEOUT"?!0:D in e}function re(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(D in e)return e[D]}}var Z=Symbol("early-exit");function oe(e,t){return{[Z]:!0,error:e,meta:t}}function se(e){return typeof e=="object"&&e!==null&&e[Z]===!0}var ue=Symbol("mapper-exception");function fe(e){return{[ue]:!0,thrown:e}}function Re(e){return typeof e=="object"&&e!==null&&e[ue]===!0}function Ce(e){return typeof e=="string"?{name:e}:e??{}}function G(e,t){let{backoff:n,initialDelay:a,maxDelay:y,jitter:A}=t,x;switch(n){case"fixed":x=a;break;case"linear":x=a*e;break;case"exponential":x=a*Math.pow(2,e-1);break}if(x=Math.min(x,y),A){let r=x*.25*Math.random();x=x+r}return Math.floor(x)}function H(e){return new Promise(t=>setTimeout(t,e))}var te=Symbol("timeout");async function xe(e,t,n){let a=new AbortController,y=t.error??{type:"STEP_TIMEOUT",stepName:n.name,stepKey:n.key,timeoutMs:t.ms,attempt:n.attempt},A,x=new Promise((I,R)=>{A=setTimeout(()=>{a.abort(),R({[te]:!0,error:y})},t.ms)}),r;t.signal?r=Promise.resolve(e(a.signal)):r=Promise.resolve(e());try{return await Promise.race([r,x])}catch(I){if(typeof I=="object"&&I!==null&&I[te]===!0){let R=I.error;if(typeof R=="object"&&R!==null&&R.type!=="STEP_TIMEOUT"){let V={timeoutMs:t.ms,stepName:n.name,stepKey:n.key,attempt:n.attempt};D in R?R[D]=V:Object.defineProperty(R,D,{value:V,enumerable:!1,writable:!0,configurable:!1})}throw R}throw I}finally{clearTimeout(A)}}var F={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,retryOn:()=>!0,onRetry:()=>{}};async function Q(e,t){let{onError:n,onEvent:a,catchUnexpected:y,workflowId:A,context:x}=t&&typeof t=="object"?t:{},r=A??crypto.randomUUID(),I=!n&&!y,R=[],V=0,X=o=>o??`step_${++V}`,E=o=>{if(o.type==="step_success"){let P=o.stepId;for(let h=R.length-1;h>=0;h--){let K=R[h];if(K.type==="race"&&!K.winnerId){K.winnerId=P;break}}}a?.(o,x)},O=oe,ee=o=>se(o),Y=(o,P)=>I?P?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:o,...P.resultCause!==void 0?{cause:P.resultCause}:{}}}:P?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:o,thrown:P.thrown}}:{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:o}}:o,ae=o=>o.origin==="result"?o.resultCause:o.thrown,ie=o=>({type:"UNEXPECTED_ERROR",cause:o.meta.origin==="result"?{type:"STEP_FAILURE",origin:"result",error:o.error,...o.meta.resultCause!==void 0?{cause:o.meta.resultCause}:{}}:{type:"STEP_FAILURE",origin:"throw",error:o.error,thrown:o.meta.thrown}});try{let P=function(w,p){let i=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),u=!1;R.push({scopeId:i,type:"parallel"});let C=()=>{if(u)return;u=!0;let c=R.findIndex(l=>l.scopeId===i);c!==-1&&R.splice(c,1),E({type:"scope_end",workflowId:r,scopeId:i,ts:Date.now(),durationMs:performance.now()-s})};E({type:"scope_start",workflowId:r,scopeId:i,scopeType:"parallel",name:w,ts:Date.now()});try{let c=await p();if(C(),!c.ok)throw n?.(c.error,w),O(c.error,{origin:"result",resultCause:c.cause});return c.value}catch(c){throw C(),c}})()},h=function(w,p){let i=Object.keys(w),s=p.name??`Parallel(${i.join(", ")})`,u=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let C=performance.now(),c=!1;R.push({scopeId:u,type:"parallel"});let l=()=>{if(c)return;c=!0;let T=R.findIndex(f=>f.scopeId===u);T!==-1&&R.splice(T,1),E({type:"scope_end",workflowId:r,scopeId:u,ts:Date.now(),durationMs:performance.now()-C})};E({type:"scope_start",workflowId:r,scopeId:u,scopeType:"parallel",name:s,ts:Date.now()});try{let T=await new Promise(_=>{if(i.length===0){_([]);return}let v=!1,S=i.length,N=new Array(i.length);for(let M=0;M<i.length;M++){let j=i[M],$=M;Promise.resolve(w[j]()).catch(k=>d({type:"PROMISE_REJECTED",cause:k},{cause:{type:"PROMISE_REJECTION",reason:k}})).then(k=>{if(!v){if(!k.ok){v=!0,_([{key:j,result:k}]);return}N[$]={key:j,result:k},S--,S===0&&_(N)}})}});l();let f={};for(let{key:_,result:v}of T){if(!v.ok)throw n?.(v.error,_),O(v.error,{origin:"result",resultCause:v.cause});f[_]=v.value}return f}catch(T){throw l(),T}})()};var ze=P,Qe=h;let o=(w,p)=>(async()=>{let i=Ce(p),{name:s,key:u,retry:C,timeout:c}=i,l=X(u),T=a,f=T?performance.now():0;if(!(typeof w=="function")){if(C&&C.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(c)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,C?.attempts??1),backoff:C?.backoff??F.backoff,initialDelay:C?.initialDelay??F.initialDelay,maxDelay:C?.maxDelay??F.maxDelay,jitter:C?.jitter??F.jitter,retryOn:C?.retryOn??F.retryOn,onRetry:C?.onRetry??F.onRetry};a&&E({type:"step_start",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now()});let N;for(let k=1;k<=S.attempts;k++){let le=T?performance.now():0;try{let m;if(typeof w=="function"?c?m=await xe(w,c,{name:s,key:u,attempt:k}):m=await w():m=await w,m.ok){let U=performance.now()-f;return E({type:"step_success",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:U}),u&&E({type:"step_complete",workflowId:r,stepKey:u,name:s,ts:Date.now(),durationMs:U,result:m}),m.value}if(N=m,k<S.attempts&&S.retryOn(m.error,k)){let U=G(k,S);E({type:"step_retry",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),attempt:k+1,maxAttempts:S.attempts,delayMs:U,error:m.error}),S.onRetry(m.error,k,U),await H(U);continue}S.attempts>1&&E({type:"step_retries_exhausted",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:performance.now()-f,attempts:k,lastError:m.error});break}catch(m){let U=performance.now()-le;if(ee(m))throw E({type:"step_aborted",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:U}),m;if(z(m)){let b=re(m),J=c?.ms??b?.timeoutMs??0;if(E({type:"step_timeout",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),timeoutMs:J,attempt:k}),k<S.attempts&&S.retryOn(m,k)){let B=G(k,S);E({type:"step_retry",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),attempt:k+1,maxAttempts:S.attempts,delayMs:B,error:m}),S.onRetry(m,k,B),await H(B);continue}S.attempts>1&&E({type:"step_retries_exhausted",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:performance.now()-f,attempts:k,lastError:m})}if(k<S.attempts&&S.retryOn(m,k)){let b=G(k,S);E({type:"step_retry",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),attempt:k+1,maxAttempts:S.attempts,delayMs:b,error:m}),S.onRetry(m,k,b),await H(b);continue}S.attempts>1&&!z(m)&&E({type:"step_retries_exhausted",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:performance.now()-f,attempts:k,lastError:m});let L=performance.now()-f;if(y){let b;try{b=y(m)}catch(J){throw fe(J)}throw E({type:"step_error",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:L,error:b}),u&&E({type:"step_complete",workflowId:r,stepKey:u,name:s,ts:Date.now(),durationMs:L,result:d(b,{cause:m}),meta:{origin:"throw",thrown:m}}),n?.(b,s),O(b,{origin:"throw",thrown:m})}else{let b={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:m}};throw E({type:"step_error",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:L,error:b}),u&&E({type:"step_complete",workflowId:r,stepKey:u,name:s,ts:Date.now(),durationMs:L,result:d(b,{cause:m}),meta:{origin:"throw",thrown:m}}),m}}}let M=N,j=performance.now()-f,$=Y(M.error,{origin:"result",resultCause:M.cause});throw E({type:"step_error",workflowId:r,stepId:l,stepKey:u,name:s,ts:Date.now(),durationMs:j,error:$}),u&&E({type:"step_complete",workflowId:r,stepKey:u,name:s,ts:Date.now(),durationMs:j,result:M,meta:{origin:"result",resultCause:M.cause}}),n?.(M.error,s),O(M.error,{origin:"result",resultCause:M.cause})})();o.try=(w,p)=>{let i=p.name,s=p.key,u=X(s),C="error"in p?()=>p.error:p.onError,c=a;return(async()=>{let l=c?performance.now():0;a&&E({type:"step_start",workflowId:r,stepId:u,stepKey:s,name:i,ts:Date.now()});try{let T=await w(),f=performance.now()-l;return E({type:"step_success",workflowId:r,stepId:u,stepKey:s,name:i,ts:Date.now(),durationMs:f}),s&&E({type:"step_complete",workflowId:r,stepKey:s,name:i,ts:Date.now(),durationMs:f,result:g(T)}),T}catch(T){let f=C(T),_=performance.now()-l,v=Y(f,{origin:"throw",thrown:T});throw E({type:"step_error",workflowId:r,stepId:u,stepKey:s,name:i,ts:Date.now(),durationMs:_,error:v}),s&&E({type:"step_complete",workflowId:r,stepKey:s,name:i,ts:Date.now(),durationMs:_,result:d(f,{cause:T}),meta:{origin:"throw",thrown:T}}),n?.(f,i),O(f,{origin:"throw",thrown:T})}})()},o.fromResult=(w,p)=>{let i=p.name,s=p.key,u=X(s),C="error"in p?()=>p.error:p.onError,c=a;return(async()=>{let l=c?performance.now():0;a&&E({type:"step_start",workflowId:r,stepId:u,stepKey:s,name:i,ts:Date.now()});let T=await w();if(T.ok){let f=performance.now()-l;return E({type:"step_success",workflowId:r,stepId:u,stepKey:s,name:i,ts:Date.now(),durationMs:f}),s&&E({type:"step_complete",workflowId:r,stepKey:s,name:i,ts:Date.now(),durationMs:f,result:g(T.value)}),T.value}else{let f=C(T.error),_=performance.now()-l,v=Y(f,{origin:"result",resultCause:T.error});throw E({type:"step_error",workflowId:r,stepId:u,stepKey:s,name:i,ts:Date.now(),durationMs:_,error:v}),s&&E({type:"step_complete",workflowId:r,stepKey:s,name:i,ts:Date.now(),durationMs:_,result:d(f,{cause:T.error}),meta:{origin:"result",resultCause:T.error}}),n?.(f,i),O(f,{origin:"result",resultCause:T.error})}})()},o.retry=(w,p)=>o(w,{name:p.name,key:p.key,retry:{attempts:p.attempts,backoff:p.backoff,initialDelay:p.initialDelay,maxDelay:p.maxDelay,jitter:p.jitter,retryOn:p.retryOn,onRetry:p.onRetry},timeout:p.timeout}),o.withTimeout=(w,p)=>o(w,{name:p.name,key:p.key,timeout:p}),o.parallel=((...w)=>{if(typeof w[0]=="string"){let p=w[0],i=w[1];return P(p,i)}else{let p=w[0],i=w[1]??{};return h(p,i)}}),o.race=(w,p)=>{let i=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),u=!1,C={scopeId:i,type:"race",winnerId:void 0};R.push(C);let c=()=>{if(u)return;u=!0;let l=R.findIndex(T=>T.scopeId===i);l!==-1&&R.splice(l,1),E({type:"scope_end",workflowId:r,scopeId:i,ts:Date.now(),durationMs:performance.now()-s,winnerId:C.winnerId})};E({type:"scope_start",workflowId:r,scopeId:i,scopeType:"race",name:w,ts:Date.now()});try{let l=await p();if(c(),!l.ok)throw n?.(l.error,w),O(l.error,{origin:"result",resultCause:l.cause});return l.value}catch(l){throw c(),l}})()},o.allSettled=(w,p)=>{let i=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let s=performance.now(),u=!1;R.push({scopeId:i,type:"allSettled"});let C=()=>{if(u)return;u=!0;let c=R.findIndex(l=>l.scopeId===i);c!==-1&&R.splice(c,1),E({type:"scope_end",workflowId:r,scopeId:i,ts:Date.now(),durationMs:performance.now()-s})};E({type:"scope_start",workflowId:r,scopeId:i,scopeType:"allSettled",name:w,ts:Date.now()});try{let c=await p();if(C(),!c.ok)throw n?.(c.error,w),O(c.error,{origin:"result",resultCause:c.cause});return c.value}catch(c){throw C(),c}})()};let pe=await e(o);return g(pe)}catch(o){if(Re(o))throw o.thrown;if(ee(o)){let h=ae(o.meta);if(y||n)return d(o.error,{cause:h});if(ne(o.error))return d(o.error,{cause:h});let K=ie(o);return d(K,{cause:h})}if(y){let h=y(o);return n?.(h,"unexpected"),d(h,{cause:o})}let P={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:o}};return n?.(P,"unexpected"),d(P,{cause:o})}}Q.strict=(e,t)=>Q(e,t);var W=class extends Error{constructor(n,a){super(`Unwrap called on an error result: ${String(n)}`);this.error=n;this.cause=a;this.name="UnwrapError"}},Se=e=>{if(e.ok)return e.value;throw new W(e.error,e.cause)},ge=(e,t)=>e.ok?e.value:t,Ae=(e,t)=>e.ok?e.value:t(e.error,e.cause);function be(e,t){try{return g(e())}catch(n){return t?d(t(n),{cause:n}):d(n)}}async function Pe(e,t){try{return g(await e)}catch(n){return t?d(t(n),{cause:n}):d(n)}}async function he(e,t){try{return g(await e())}catch(n){return t?d(t(n),{cause:n}):d(n)}}function _e(e,t){return e!=null?g(e):d(t())}function ve(e,t){return e.ok?g(t(e.value)):e}function Me(e,t){return e.ok?e:d(t(e.error),{cause:e.cause})}function Ie(e,t){return e.ok?t.ok(e.value):t.err(e.error,e.cause)}function Oe(e,t){return e.ok?t(e.value):e}function Ue(e,t){return e.ok&&t(e.value),e}function De(e,t){return e.ok||t(e.error,e.cause),e}function Ke(e,t,n){if(!e.ok)return e;try{return g(t(e.value))}catch(a){return d(n(a),{cause:a})}}function je(e,t,n){if(e.ok)return e;try{return d(t(e.error),{cause:e.cause})}catch(a){return d(n(a),{cause:a})}}function Fe(e,t,n){return e.ok?g(t(e.value)):d(n(e.error),{cause:e.cause})}function Ne(e,t){return e.ok?e:t(e.error,e.cause)}async function Ve(e,t){let n=await e;return n.ok?n:t(n.error,n.cause)}function Le(e,t){return e.ok?g(e.value):g(t(e.error,e.cause))}async function We(e,t){let n=await e;return n.ok?g(n.value):g(await t(n.error,n.cause))}function Xe(e){let t=[];for(let n of e){if(!n.ok)return n;t.push(n.value)}return g(t)}async function Ye(e){return e.length===0?g([]):new Promise(t=>{let n=!1,a=e.length,y=new Array(e.length);for(let A=0;A<e.length;A++){let x=A;Promise.resolve(e[x]).catch(r=>d({type:"PROMISE_REJECTED",cause:r},{cause:{type:"PROMISE_REJECTION",reason:r}})).then(r=>{if(!n){if(!r.ok){n=!0,t(r);return}y[x]=r.value,a--,a===0&&t(g(y))}})}})}function $e(e){let t=[],n=[];for(let a of e)a.ok?t.push(a.value):n.push({error:a.error,cause:a.cause});return n.length>0?d(n):g(t)}function Je(e){let t=[],n=[];for(let a of e)a.ok?t.push(a.value):n.push(a.error);return{values:t,errors:n}}function Be(e){if(e.length===0)return d({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 qe(e){return e.length===0?d({type:"EMPTY_INPUT",message:"anyAsync() requires at least one Result"}):new Promise(t=>{let n=!1,a=e.length,y=null;for(let A of e)Promise.resolve(A).catch(x=>d({type:"PROMISE_REJECTED",cause:x},{cause:{type:"PROMISE_REJECTION",reason:x}})).then(x=>{if(!n){if(x.ok){n=!0,t(x);return}y||(y=x),a--,a===0&&t(y)}})})}async function Ge(e){let t=await Promise.all(e.map(y=>Promise.resolve(y).then(A=>({status:"result",result:A})).catch(A=>({status:"rejected",error:{type:"PROMISE_REJECTED",cause:A},cause:{type:"PROMISE_REJECTION",reason:A}})))),n=[],a=[];for(let y of t)y.status==="rejected"?a.push({error:y.error,cause:y.cause}):y.result.ok?n.push(y.result.value):a.push({error:y.result.error,cause:y.result.cause});return a.length>0?d(a):g(n)}0&&(module.exports={EARLY_EXIT_SYMBOL,STEP_TIMEOUT_MARKER,UnwrapError,all,allAsync,allSettled,allSettledAsync,andThen,any,anyAsync,bimap,createEarlyExit,err,from,fromNullable,fromPromise,getStepTimeoutMeta,isEarlyExit,isErr,isOk,isStepTimeoutError,isUnexpectedError,map,mapError,mapErrorTry,mapTry,match,ok,orElse,orElseAsync,partition,recover,recoverAsync,run,tap,tapError,tryAsync,unwrap,unwrapOr,unwrapOrElse});
2
2
  //# sourceMappingURL=core.cjs.map