@doeixd/machine 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/development/index.js +120 -0
- package/dist/cjs/development/index.js.map +2 -2
- package/dist/cjs/production/index.js +4 -4
- package/dist/esm/development/index.js +120 -0
- package/dist/esm/development/index.js.map +2 -2
- package/dist/esm/production/index.js +5 -5
- package/dist/types/extract.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/primitives.d.ts +117 -17
- package/dist/types/primitives.d.ts.map +1 -1
- package/package.json +9 -6
- package/scripts/extract-statechart.ts +351 -0
- package/src/extract.ts +59 -19
- package/src/index.ts +4 -0
- package/src/primitives.ts +287 -27
package/src/primitives.ts
CHANGED
|
@@ -228,6 +228,7 @@ export function describe<
|
|
|
228
228
|
* Annotates a transition with a Guard condition.
|
|
229
229
|
* Note: This only adds metadata. You must still implement the `if` check inside your function.
|
|
230
230
|
*
|
|
231
|
+
* @deprecated Use the runtime `guard()` primitive instead. Its `options.description` is used for static analysis.
|
|
231
232
|
* @param guard - Object containing the name and optional description of the guard.
|
|
232
233
|
* @param transition - The transition function to guard.
|
|
233
234
|
* @example
|
|
@@ -316,9 +317,9 @@ export function action<
|
|
|
316
317
|
/**
|
|
317
318
|
* Configuration options for guard behavior when conditions fail.
|
|
318
319
|
*/
|
|
319
|
-
export interface GuardOptions<C extends object = any> {
|
|
320
|
+
export interface GuardOptions<C extends object = any, TFailure extends Machine<any> = Machine<C>> {
|
|
320
321
|
/** What to do when guard fails */
|
|
321
|
-
onFail?: 'throw' | 'ignore' | GuardFallback<C>;
|
|
322
|
+
onFail?: 'throw' | 'ignore' | GuardFallback<C, TFailure>;
|
|
322
323
|
|
|
323
324
|
/** Custom error message for 'throw' mode */
|
|
324
325
|
errorMessage?: string;
|
|
@@ -330,31 +331,36 @@ export interface GuardOptions<C extends object = any> {
|
|
|
330
331
|
/**
|
|
331
332
|
* A fallback machine or function that returns a machine when guard fails.
|
|
332
333
|
*/
|
|
333
|
-
export type GuardFallback<C extends object> =
|
|
334
|
-
| ((this: Machine<C>, ...args: any[]) =>
|
|
335
|
-
|
|
|
334
|
+
export type GuardFallback<C extends object, TFailure extends Machine<any> = Machine<C>> =
|
|
335
|
+
| ((this: Machine<C>, ...args: any[]) => TFailure)
|
|
336
|
+
| TFailure;
|
|
336
337
|
|
|
337
338
|
/**
|
|
338
339
|
* A guarded transition that checks conditions at runtime before executing.
|
|
339
340
|
* Can be called with either machine or context as 'this' binding.
|
|
340
341
|
*/
|
|
341
|
-
export type GuardedTransition<
|
|
342
|
-
|
|
342
|
+
export type GuardedTransition<
|
|
343
|
+
C extends object,
|
|
344
|
+
TSuccess extends Machine<any>,
|
|
345
|
+
TFailure extends Machine<any> = Machine<C>
|
|
346
|
+
> = {
|
|
347
|
+
(...args: any[]): TSuccess | TFailure | Promise<TSuccess | TFailure>;
|
|
343
348
|
readonly __guard: true;
|
|
344
349
|
readonly condition: (ctx: C, ...args: any[]) => boolean | Promise<boolean>;
|
|
345
|
-
readonly transition: (...args: any[]) =>
|
|
350
|
+
readonly transition: (...args: any[]) => TSuccess;
|
|
346
351
|
};
|
|
347
352
|
|
|
348
353
|
/**
|
|
349
|
-
* Creates a runtime guard that checks conditions before executing transitions.
|
|
350
|
-
* This provides actual runtime protection
|
|
354
|
+
* Creates a synchronous runtime guard that checks conditions before executing transitions.
|
|
355
|
+
* This provides actual runtime protection with synchronous execution - use this for the majority of cases.
|
|
351
356
|
*
|
|
352
357
|
* @template C - The context type
|
|
353
|
-
* @template
|
|
354
|
-
* @
|
|
358
|
+
* @template TSuccess - The transition return type when condition passes
|
|
359
|
+
* @template TFailure - The fallback return type when condition fails (defaults to Machine<C>)
|
|
360
|
+
* @param condition - Synchronous function that returns true if transition should proceed
|
|
355
361
|
* @param transition - The transition function to execute if condition passes
|
|
356
362
|
* @param options - Configuration for guard failure behavior
|
|
357
|
-
* @returns A guarded transition function
|
|
363
|
+
* @returns A synchronous guarded transition function
|
|
358
364
|
*
|
|
359
365
|
* @example
|
|
360
366
|
* ```typescript
|
|
@@ -368,22 +374,131 @@ export type GuardedTransition<C extends object, T extends Machine<any>> = {
|
|
|
368
374
|
* )
|
|
369
375
|
* });
|
|
370
376
|
*
|
|
371
|
-
* machine.withdraw(50); // ✅ Works
|
|
377
|
+
* machine.withdraw(50); // ✅ Works synchronously
|
|
372
378
|
* machine.withdraw(200); // ❌ Throws "Insufficient funds"
|
|
373
379
|
* ```
|
|
374
380
|
*/
|
|
375
|
-
export function guard<
|
|
381
|
+
export function guard<
|
|
382
|
+
C extends object,
|
|
383
|
+
TSuccess extends Machine<any>,
|
|
384
|
+
TFailure extends Machine<any> = Machine<C>
|
|
385
|
+
>(
|
|
386
|
+
condition: (ctx: C, ...args: any[]) => boolean,
|
|
387
|
+
transition: (...args: any[]) => TSuccess,
|
|
388
|
+
options: GuardOptions<C, TFailure> = {}
|
|
389
|
+
): (...args: any[]) => TSuccess | TFailure {
|
|
390
|
+
const { onFail = 'throw', errorMessage, description } = options;
|
|
391
|
+
|
|
392
|
+
// Merge defaults into options for the metadata
|
|
393
|
+
const fullOptions = { ...options, onFail, errorMessage, description };
|
|
394
|
+
|
|
395
|
+
// Create the guarded transition function (synchronous)
|
|
396
|
+
const guardedTransition = function(this: C | Machine<C>, ...args: any[]): TSuccess | TFailure {
|
|
397
|
+
// Detect if 'this' is a machine or just context
|
|
398
|
+
const isMachine = typeof this === 'object' && 'context' in this;
|
|
399
|
+
const ctx = isMachine ? (this as Machine<C>).context : (this as C);
|
|
400
|
+
|
|
401
|
+
// Evaluate the condition (synchronously)
|
|
402
|
+
const conditionResult = condition(ctx, ...args);
|
|
403
|
+
|
|
404
|
+
if (conditionResult) {
|
|
405
|
+
// Condition passed, execute the transition
|
|
406
|
+
// Transition functions expect 'this' to be the context
|
|
407
|
+
const contextForTransition = isMachine ? (this as Machine<C>).context : (this as C);
|
|
408
|
+
return transition.apply(contextForTransition, args);
|
|
409
|
+
} else {
|
|
410
|
+
// Condition failed, handle according to options
|
|
411
|
+
if (onFail === 'throw') {
|
|
412
|
+
const message = errorMessage || 'Guard condition failed';
|
|
413
|
+
throw new Error(message);
|
|
414
|
+
} else if (onFail === 'ignore') {
|
|
415
|
+
if (isMachine) {
|
|
416
|
+
// Return the current machine unchanged
|
|
417
|
+
return this as TSuccess | TFailure;
|
|
418
|
+
} else {
|
|
419
|
+
// Cannot ignore when called with context binding
|
|
420
|
+
throw new Error('Cannot use "ignore" mode with context-only binding. Use full machine binding or provide fallback.');
|
|
421
|
+
}
|
|
422
|
+
} else if (typeof onFail === 'function') {
|
|
423
|
+
// Custom fallback function - call with machine as 'this'
|
|
424
|
+
if (isMachine) {
|
|
425
|
+
return onFail.apply(this as Machine<C>, args) as TSuccess | TFailure;
|
|
426
|
+
} else {
|
|
427
|
+
throw new Error('Cannot use function fallback with context-only binding. Use full machine binding.');
|
|
428
|
+
}
|
|
429
|
+
} else {
|
|
430
|
+
// Static fallback machine
|
|
431
|
+
return onFail as TSuccess | TFailure;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
// Attach metadata for type branding and statechart extraction
|
|
437
|
+
Object.defineProperty(guardedTransition, '__guard', { value: true, enumerable: false });
|
|
438
|
+
Object.defineProperty(guardedTransition, 'condition', { value: condition, enumerable: false });
|
|
439
|
+
Object.defineProperty(guardedTransition, 'transition', { value: transition, enumerable: false });
|
|
440
|
+
Object.defineProperty(guardedTransition, 'options', { value: fullOptions, enumerable: false });
|
|
441
|
+
|
|
442
|
+
// Attach runtime metadata for statechart extraction
|
|
443
|
+
attachRuntimeMeta(guardedTransition, {
|
|
444
|
+
description: description || 'Synchronous guarded transition',
|
|
445
|
+
guards: [{ name: 'runtime_guard', description: description || 'Synchronous condition check' }]
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
return guardedTransition;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Creates a runtime guard that checks conditions before executing transitions.
|
|
453
|
+
* This provides actual runtime protection, unlike the `guarded` primitive which only adds metadata.
|
|
454
|
+
* Use this when your condition or transition logic is asynchronous.
|
|
455
|
+
*
|
|
456
|
+
* @template C - The context type
|
|
457
|
+
* @template TSuccess - The transition return type when condition passes
|
|
458
|
+
* @template TFailure - The fallback return type when condition fails (defaults to Machine<C>)
|
|
459
|
+
* @param condition - Function that returns true if transition should proceed (can be async)
|
|
460
|
+
* @param transition - The transition function to execute if condition passes
|
|
461
|
+
* @param options - Configuration for guard failure behavior
|
|
462
|
+
* @returns A guarded transition function that returns a Promise
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* ```typescript
|
|
466
|
+
* const machine = createMachine({ balance: 100 }, {
|
|
467
|
+
* withdraw: guardAsync(
|
|
468
|
+
* async (ctx, amount) => {
|
|
469
|
+
* // Simulate API call to check balance
|
|
470
|
+
* await new Promise(resolve => setTimeout(resolve, 100));
|
|
471
|
+
* return ctx.balance >= amount;
|
|
472
|
+
* },
|
|
473
|
+
* async function(amount: number) {
|
|
474
|
+
* // Simulate API call to process withdrawal
|
|
475
|
+
* await new Promise(resolve => setTimeout(resolve, 100));
|
|
476
|
+
* return createMachine({ balance: this.balance - amount }, this);
|
|
477
|
+
* },
|
|
478
|
+
* { onFail: 'throw', errorMessage: 'Insufficient funds' }
|
|
479
|
+
* )
|
|
480
|
+
* });
|
|
481
|
+
*
|
|
482
|
+
* await machine.withdraw(50); // ✅ Works
|
|
483
|
+
* await machine.withdraw(200); // ❌ Throws "Insufficient funds"
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
export function guardAsync<
|
|
487
|
+
C extends object,
|
|
488
|
+
TSuccess extends Machine<any>,
|
|
489
|
+
TFailure extends Machine<any> = Machine<C>
|
|
490
|
+
>(
|
|
376
491
|
condition: (ctx: C, ...args: any[]) => boolean | Promise<boolean>,
|
|
377
|
-
transition: (...args: any[]) =>
|
|
378
|
-
options: GuardOptions<C> = {}
|
|
379
|
-
): GuardedTransition<C,
|
|
492
|
+
transition: (...args: any[]) => TSuccess,
|
|
493
|
+
options: GuardOptions<C, TFailure> = {}
|
|
494
|
+
): GuardedTransition<C, TSuccess, TFailure> {
|
|
380
495
|
const { onFail = 'throw', errorMessage, description } = options;
|
|
381
496
|
|
|
382
497
|
// Merge defaults into options for the metadata
|
|
383
498
|
const fullOptions = { ...options, onFail, errorMessage, description };
|
|
384
499
|
|
|
385
500
|
// Create the guarded transition function
|
|
386
|
-
const guardedTransition = async function(this: C | Machine<C>, ...args: any[]): Promise<
|
|
501
|
+
const guardedTransition = async function(this: C | Machine<C>, ...args: any[]): Promise<TSuccess | TFailure> {
|
|
387
502
|
// Detect if 'this' is a machine or just context
|
|
388
503
|
const isMachine = typeof this === 'object' && 'context' in this;
|
|
389
504
|
const ctx = isMachine ? (this as Machine<C>).context : (this as C);
|
|
@@ -404,7 +519,7 @@ export function guard<C extends object, T extends Machine<any>>(
|
|
|
404
519
|
} else if (onFail === 'ignore') {
|
|
405
520
|
if (isMachine) {
|
|
406
521
|
// Return the current machine unchanged
|
|
407
|
-
return this as
|
|
522
|
+
return this as TSuccess | TFailure;
|
|
408
523
|
} else {
|
|
409
524
|
// Cannot ignore when called with context binding
|
|
410
525
|
throw new Error('Cannot use "ignore" mode with context-only binding. Use full machine binding or provide fallback.');
|
|
@@ -412,13 +527,13 @@ export function guard<C extends object, T extends Machine<any>>(
|
|
|
412
527
|
} else if (typeof onFail === 'function') {
|
|
413
528
|
// Custom fallback function - call with machine as 'this'
|
|
414
529
|
if (isMachine) {
|
|
415
|
-
return onFail.apply(this as Machine<C>, args);
|
|
530
|
+
return onFail.apply(this as Machine<C>, args) as TSuccess | TFailure;
|
|
416
531
|
} else {
|
|
417
532
|
throw new Error('Cannot use function fallback with context-only binding. Use full machine binding.');
|
|
418
533
|
}
|
|
419
534
|
} else {
|
|
420
535
|
// Static fallback machine
|
|
421
|
-
return onFail;
|
|
536
|
+
return onFail as TSuccess | TFailure;
|
|
422
537
|
}
|
|
423
538
|
}
|
|
424
539
|
};
|
|
@@ -435,15 +550,113 @@ export function guard<C extends object, T extends Machine<any>>(
|
|
|
435
550
|
guards: [{ name: 'runtime_guard', description: description || 'Runtime condition check' }]
|
|
436
551
|
});
|
|
437
552
|
|
|
438
|
-
return guardedTransition as GuardedTransition<C,
|
|
553
|
+
return guardedTransition as GuardedTransition<C, TSuccess, TFailure>;
|
|
439
554
|
}
|
|
440
555
|
|
|
441
556
|
/**
|
|
442
|
-
*
|
|
443
|
-
*
|
|
557
|
+
* Creates a synchronous guard that checks conditions before executing transitions.
|
|
558
|
+
* This is the synchronous counterpart to `guard()` - use this when your machine
|
|
559
|
+
* doesn't need async transitions to avoid unnecessary Promise overhead.
|
|
444
560
|
*
|
|
445
561
|
* @template C - The context type
|
|
446
|
-
* @
|
|
562
|
+
* @template T - The transition return type
|
|
563
|
+
* @param condition - Function that returns true if transition should proceed (must be synchronous)
|
|
564
|
+
* @param transition - The transition function to execute if condition passes (must be synchronous)
|
|
565
|
+
* @param options - Configuration for guard failure behavior
|
|
566
|
+
* @returns A synchronous guarded transition function
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* const machine = createMachine({ balance: 100 }, {
|
|
571
|
+
* withdraw: guardSync(
|
|
572
|
+
* (ctx, amount) => ctx.balance >= amount,
|
|
573
|
+
* function(amount: number) {
|
|
574
|
+
* return createMachine({ balance: this.balance - amount }, this);
|
|
575
|
+
* },
|
|
576
|
+
* { onFail: 'throw', errorMessage: 'Insufficient funds' }
|
|
577
|
+
* )
|
|
578
|
+
* });
|
|
579
|
+
*
|
|
580
|
+
* machine.withdraw(50); // ✅ Works synchronously
|
|
581
|
+
* machine.withdraw(200); // ❌ Throws "Insufficient funds"
|
|
582
|
+
* ```
|
|
583
|
+
*/
|
|
584
|
+
export function guardSync<
|
|
585
|
+
C extends object,
|
|
586
|
+
TSuccess extends Machine<any>,
|
|
587
|
+
TFailure extends Machine<any> = Machine<C>
|
|
588
|
+
>(
|
|
589
|
+
condition: (ctx: C, ...args: any[]) => boolean,
|
|
590
|
+
transition: (...args: any[]) => TSuccess,
|
|
591
|
+
options: GuardOptions<C, TFailure> = {}
|
|
592
|
+
): GuardedTransition<C, TSuccess, TFailure> {
|
|
593
|
+
const { onFail = 'throw', errorMessage, description } = options;
|
|
594
|
+
|
|
595
|
+
// Merge defaults into options for the metadata
|
|
596
|
+
const fullOptions = { ...options, onFail, errorMessage, description };
|
|
597
|
+
|
|
598
|
+
// Create the guarded transition function (synchronous)
|
|
599
|
+
const guardedTransition = function(this: C | Machine<C>, ...args: any[]): TSuccess | TFailure {
|
|
600
|
+
// Detect if 'this' is a machine or just context
|
|
601
|
+
const isMachine = typeof this === 'object' && 'context' in this;
|
|
602
|
+
const ctx = isMachine ? (this as Machine<C>).context : (this as C);
|
|
603
|
+
|
|
604
|
+
// Evaluate the condition (synchronously)
|
|
605
|
+
const conditionResult = condition(ctx, ...args);
|
|
606
|
+
|
|
607
|
+
if (conditionResult) {
|
|
608
|
+
// Condition passed, execute the transition
|
|
609
|
+
// Transition functions expect 'this' to be the context
|
|
610
|
+
const contextForTransition = isMachine ? (this as Machine<C>).context : (this as C);
|
|
611
|
+
return transition.apply(contextForTransition, args);
|
|
612
|
+
} else {
|
|
613
|
+
// Condition failed, handle according to options
|
|
614
|
+
if (onFail === 'throw') {
|
|
615
|
+
const message = errorMessage || 'Guard condition failed';
|
|
616
|
+
throw new Error(message);
|
|
617
|
+
} else if (onFail === 'ignore') {
|
|
618
|
+
if (isMachine) {
|
|
619
|
+
// Return the current machine unchanged
|
|
620
|
+
return this as TSuccess | TFailure;
|
|
621
|
+
} else {
|
|
622
|
+
// Cannot ignore when called with context binding
|
|
623
|
+
throw new Error('Cannot use "ignore" mode with context-only binding. Use full machine binding or provide fallback.');
|
|
624
|
+
}
|
|
625
|
+
} else if (typeof onFail === 'function') {
|
|
626
|
+
// Custom fallback function - call with machine as 'this'
|
|
627
|
+
if (isMachine) {
|
|
628
|
+
return onFail.apply(this as Machine<C>, args) as TSuccess | TFailure;
|
|
629
|
+
} else {
|
|
630
|
+
throw new Error('Cannot use function fallback with context-only binding. Use full machine binding.');
|
|
631
|
+
}
|
|
632
|
+
} else {
|
|
633
|
+
// Static fallback machine
|
|
634
|
+
return onFail as TSuccess | TFailure;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
// Attach metadata for type branding and statechart extraction
|
|
640
|
+
Object.defineProperty(guardedTransition, '__guard', { value: true, enumerable: false });
|
|
641
|
+
Object.defineProperty(guardedTransition, 'condition', { value: condition, enumerable: false });
|
|
642
|
+
Object.defineProperty(guardedTransition, 'transition', { value: transition, enumerable: false });
|
|
643
|
+
Object.defineProperty(guardedTransition, 'options', { value: fullOptions, enumerable: false });
|
|
644
|
+
|
|
645
|
+
// Attach runtime metadata for statechart extraction
|
|
646
|
+
attachRuntimeMeta(guardedTransition, {
|
|
647
|
+
description: description || 'Synchronous guarded transition',
|
|
648
|
+
guards: [{ name: 'runtime_guard_sync', description: description || 'Synchronous condition check' }]
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
return guardedTransition as GuardedTransition<C, TSuccess, TFailure>;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Fluent API for creating synchronous guarded transitions.
|
|
656
|
+
* Provides a more readable way to define conditional transitions with synchronous execution.
|
|
657
|
+
*
|
|
658
|
+
* @template C - The context type
|
|
659
|
+
* @param condition - Synchronous function that returns true if transition should proceed
|
|
447
660
|
* @returns A fluent interface for defining the guarded transition
|
|
448
661
|
*
|
|
449
662
|
* @example
|
|
@@ -460,7 +673,7 @@ export function guard<C extends object, T extends Machine<any>>(
|
|
|
460
673
|
* ```
|
|
461
674
|
*/
|
|
462
675
|
export function whenGuard<C extends object>(
|
|
463
|
-
condition: (ctx: C, ...args: any[]) => boolean
|
|
676
|
+
condition: (ctx: C, ...args: any[]) => boolean
|
|
464
677
|
) {
|
|
465
678
|
return {
|
|
466
679
|
/**
|
|
@@ -480,6 +693,53 @@ export function whenGuard<C extends object>(
|
|
|
480
693
|
};
|
|
481
694
|
}
|
|
482
695
|
|
|
696
|
+
/**
|
|
697
|
+
* Fluent API for creating asynchronous guarded transitions.
|
|
698
|
+
* Provides a more readable way to define conditional transitions with async execution.
|
|
699
|
+
*
|
|
700
|
+
* @template C - The context type
|
|
701
|
+
* @param condition - Function that returns true if transition should proceed (can be async)
|
|
702
|
+
* @returns A fluent interface for defining the guarded transition
|
|
703
|
+
*
|
|
704
|
+
* @example
|
|
705
|
+
* ```typescript
|
|
706
|
+
* const machine = createMachine({ isAdmin: false }, {
|
|
707
|
+
* deleteUser: whenGuardAsync(async (ctx) => {
|
|
708
|
+
* // Simulate API call
|
|
709
|
+
* await checkPermissions(ctx.userId);
|
|
710
|
+
* return ctx.isAdmin;
|
|
711
|
+
* })
|
|
712
|
+
* .do(async function(userId: string) {
|
|
713
|
+
* await deleteUserFromDB(userId);
|
|
714
|
+
* return createMachine({ ...this.context, deleted: userId }, this);
|
|
715
|
+
* })
|
|
716
|
+
* .else(function() {
|
|
717
|
+
* return createMachine({ ...this.context, error: 'Unauthorized' }, this);
|
|
718
|
+
* })
|
|
719
|
+
* });
|
|
720
|
+
* ```
|
|
721
|
+
*/
|
|
722
|
+
export function whenGuardAsync<C extends object>(
|
|
723
|
+
condition: (ctx: C, ...args: any[]) => boolean | Promise<boolean>
|
|
724
|
+
) {
|
|
725
|
+
return {
|
|
726
|
+
/**
|
|
727
|
+
* Define the transition to execute when the condition passes.
|
|
728
|
+
* Returns a guarded transition that can optionally have an else clause.
|
|
729
|
+
*/
|
|
730
|
+
do<T extends Machine<any>>(transition: (...args: any[]) => T) {
|
|
731
|
+
const guarded = guardAsync(condition, transition);
|
|
732
|
+
|
|
733
|
+
// Add fluent else method to the guarded transition
|
|
734
|
+
(guarded as any).else = function<F extends Machine<any>>(fallback: (...args: any[]) => F) {
|
|
735
|
+
return guardAsync(condition, transition, { onFail: fallback });
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
return guarded;
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
|
|
483
743
|
/**
|
|
484
744
|
* Flexible metadata wrapper for functional and type-state patterns.
|
|
485
745
|
*
|