@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 +255 -19
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +60 -7
- package/dist/core.d.ts +60 -7
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +5 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/visualize.cjs +1188 -6
- package/dist/visualize.cjs.map +1 -1
- package/dist/visualize.d.cts +467 -1
- package/dist/visualize.d.ts +467 -1
- package/dist/visualize.js +1188 -6
- package/dist/visualize.js.map +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +50 -0
- package/dist/workflow.d.ts +50 -0
- package/dist/workflow.js +1 -1
- package/dist/workflow.js.map +1 -1
- package/docs/advanced.md +368 -3
- package/package.json +1 -1
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
|
-
|
|
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:
|
|
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
|
-
//
|
|
381
|
-
|
|
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,
|
|
730
|
+
import { createWorkflow, createStepCollector } from '@jagreehal/workflow';
|
|
551
731
|
|
|
552
|
-
|
|
732
|
+
// Collect state during execution
|
|
733
|
+
const collector = createStepCollector();
|
|
553
734
|
const workflow = createWorkflow(deps, {
|
|
554
|
-
onEvent:
|
|
555
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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),
|
|
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?
|
|
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
|