xstate 5.0.0-beta.12 → 5.0.0-beta.14

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.
Files changed (57) hide show
  1. package/actions/dist/xstate-actions.cjs.js +1 -1
  2. package/actions/dist/xstate-actions.development.cjs.js +1 -1
  3. package/actions/dist/xstate-actions.development.esm.js +1 -1
  4. package/actions/dist/xstate-actions.esm.js +1 -1
  5. package/actions/dist/xstate-actions.umd.min.js +1 -1
  6. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  7. package/actors/dist/xstate-actors.cjs.js +1 -1
  8. package/actors/dist/xstate-actors.development.cjs.js +1 -1
  9. package/actors/dist/xstate-actors.development.esm.js +1 -1
  10. package/actors/dist/xstate-actors.esm.js +1 -1
  11. package/actors/dist/xstate-actors.umd.min.js +1 -1
  12. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  13. package/dist/{actions-e4c704f3.cjs.js → actions-17c3bcfa.cjs.js} +803 -853
  14. package/dist/{actions-b34f6ce7.esm.js → actions-444a17c3.esm.js} +804 -854
  15. package/dist/{actions-c8b9504d.development.esm.js → actions-60622c0c.development.esm.js} +829 -879
  16. package/dist/{actions-d9c19f35.development.cjs.js → actions-73b8d456.development.cjs.js} +828 -878
  17. package/dist/declarations/src/Machine.d.ts +3 -3
  18. package/dist/declarations/src/SimulatedClock.d.ts +1 -1
  19. package/dist/declarations/src/State.d.ts +4 -10
  20. package/dist/declarations/src/StateMachine.d.ts +8 -13
  21. package/dist/declarations/src/StateNode.d.ts +4 -4
  22. package/dist/declarations/src/actionTypes.d.ts +1 -1
  23. package/dist/declarations/src/actions/assign.d.ts +1 -1
  24. package/dist/declarations/src/actions/cancel.d.ts +2 -2
  25. package/dist/declarations/src/actions/choose.d.ts +2 -2
  26. package/dist/declarations/src/actions/log.d.ts +2 -2
  27. package/dist/declarations/src/actions/pure.d.ts +2 -2
  28. package/dist/declarations/src/actions/raise.d.ts +1 -1
  29. package/dist/declarations/src/actions/send.d.ts +2 -2
  30. package/dist/declarations/src/actions/stop.d.ts +1 -1
  31. package/dist/declarations/src/actions.d.ts +10 -10
  32. package/dist/declarations/src/actors/callback.d.ts +2 -2
  33. package/dist/declarations/src/actors/index.d.ts +6 -6
  34. package/dist/declarations/src/actors/observable.d.ts +8 -6
  35. package/dist/declarations/src/actors/promise.d.ts +4 -3
  36. package/dist/declarations/src/actors/transition.d.ts +4 -4
  37. package/dist/declarations/src/dev/index.d.ts +1 -1
  38. package/dist/declarations/src/guards.d.ts +2 -2
  39. package/dist/declarations/src/index.d.ts +22 -22
  40. package/dist/declarations/src/interpreter.d.ts +18 -18
  41. package/dist/declarations/src/stateUtils.d.ts +8 -10
  42. package/dist/declarations/src/typegenTypes.d.ts +1 -1
  43. package/dist/declarations/src/types.d.ts +29 -39
  44. package/dist/declarations/src/utils.d.ts +9 -9
  45. package/dist/declarations/src/waitFor.d.ts +1 -1
  46. package/dist/xstate.cjs.js +13 -37
  47. package/dist/xstate.development.cjs.js +13 -37
  48. package/dist/xstate.development.esm.js +14 -38
  49. package/dist/xstate.esm.js +14 -38
  50. package/dist/xstate.umd.min.js +1 -1
  51. package/dist/xstate.umd.min.js.map +1 -1
  52. package/guards/dist/xstate-guards.cjs.js +1 -1
  53. package/guards/dist/xstate-guards.development.cjs.js +1 -1
  54. package/guards/dist/xstate-guards.development.esm.js +1 -1
  55. package/guards/dist/xstate-guards.esm.js +1 -1
  56. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  57. package/package.json +1 -1
@@ -10,10 +10,10 @@ import { devToolsAdapter } from '../dev/dist/xstate-dev.development.esm.js';
10
10
  */
11
11
 
12
12
  // TODO: do not accept machines without all implementations
13
- // we should also accept a raw machine as a behavior here
14
- // or just make machine a behavior
13
+ // we should also accept a raw machine as actor logic here
14
+ // or just make machine actor logic
15
15
 
16
- // TODO: narrow this to behaviors from machine
16
+ // TODO: narrow this to logic from machine
17
17
 
18
18
  // TODO: fix last param
19
19
 
@@ -477,6 +477,59 @@ function sendTo(actor, event, options) {
477
477
  });
478
478
  }
479
479
 
480
+ const cache = new WeakMap();
481
+ function memo(object, key, fn) {
482
+ let memoizedData = cache.get(object);
483
+ if (!memoizedData) {
484
+ memoizedData = {
485
+ [key]: fn()
486
+ };
487
+ cache.set(object, memoizedData);
488
+ } else if (!(key in memoizedData)) {
489
+ memoizedData[key] = fn();
490
+ }
491
+ return memoizedData[key];
492
+ }
493
+
494
+ /**
495
+ * Cancels an in-flight `send(...)` action. A canceled sent action will not
496
+ * be executed, nor will its event be sent, unless it has already been sent
497
+ * (e.g., if `cancel(...)` is called after the `send(...)` action's `delay`).
498
+ *
499
+ * @param sendId The `id` of the `send(...)` action to cancel.
500
+ */
501
+
502
+ function cancel(sendId) {
503
+ return createDynamicAction({
504
+ type: cancel$1,
505
+ params: {
506
+ sendId
507
+ }
508
+ }, (event, {
509
+ state,
510
+ actorContext
511
+ }) => {
512
+ const resolvedSendId = isFunction(sendId) ? sendId({
513
+ context: state.context,
514
+ event,
515
+ self: actorContext?.self ?? {},
516
+ system: actorContext?.system
517
+ }) : sendId;
518
+ return [state, {
519
+ type: 'xstate.cancel',
520
+ params: {
521
+ sendId: resolvedSendId
522
+ },
523
+ execute: actorCtx => {
524
+ const interpreter = actorCtx.self;
525
+ interpreter.cancel(resolvedSendId);
526
+ }
527
+ }];
528
+ });
529
+ }
530
+
531
+ const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
532
+
480
533
  class Mailbox {
481
534
  constructor(_process) {
482
535
  this._process = _process;
@@ -544,537 +597,92 @@ class Mailbox {
544
597
  }
545
598
  }
546
599
 
547
- const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
548
-
549
- /**
550
- * Returns an actor behavior from a transition function and its initial state.
551
- *
552
- * A transition function is a function that takes the current state and an event and returns the next state.
553
- *
554
- * @param transition The transition function that returns the next state given the current state and event.
555
- * @param initialState The initial state of the transition function.
556
- * @returns An actor behavior
557
- */
558
- function fromTransition(transition, initialState) {
559
- const behavior = {
560
- config: transition,
561
- transition: (state, event, actorContext) => {
562
- return transition(state, event, actorContext);
563
- },
564
- getInitialState: (_, input) => {
565
- return typeof initialState === 'function' ? initialState({
566
- input
567
- }) : initialState;
568
- },
569
- getSnapshot: state => state,
570
- getPersistedState: state => state,
571
- restoreState: state => state
572
- };
573
- return behavior;
574
- }
575
-
576
- function fromPromise(
577
- // TODO: add types
578
- promiseCreator) {
579
- const resolveEventType = '$$xstate.resolve';
580
- const rejectEventType = '$$xstate.reject';
581
-
582
- // TODO: add event types
583
- const behavior = {
584
- config: promiseCreator,
585
- transition: (state, event) => {
586
- if (state.status !== 'active') {
587
- return state;
588
- }
589
- switch (event.type) {
590
- case resolveEventType:
591
- return {
592
- ...state,
593
- status: 'done',
594
- data: event.data,
595
- input: undefined
596
- };
597
- case rejectEventType:
598
- return {
599
- ...state,
600
- status: 'error',
601
- data: event.data,
602
- input: undefined
603
- };
604
- case stopSignalType:
605
- return {
606
- ...state,
607
- status: 'canceled',
608
- input: undefined
609
- };
610
- default:
611
- return state;
612
- }
600
+ function createSystem() {
601
+ let sessionIdCounter = 0;
602
+ const children = new Map();
603
+ const keyedActors = new Map();
604
+ const reverseKeyedActors = new WeakMap();
605
+ const system = {
606
+ _bookId: () => `x:${sessionIdCounter++}`,
607
+ _register: (sessionId, actorRef) => {
608
+ children.set(sessionId, actorRef);
609
+ return sessionId;
613
610
  },
614
- start: (state, {
615
- self
616
- }) => {
617
- // TODO: determine how to allow customizing this so that promises
618
- // can be restarted if necessary
619
- if (state.status !== 'active') {
620
- return;
611
+ _unregister: actorRef => {
612
+ children.delete(actorRef.sessionId);
613
+ const systemId = reverseKeyedActors.get(actorRef);
614
+ if (systemId !== undefined) {
615
+ keyedActors.delete(systemId);
616
+ reverseKeyedActors.delete(actorRef);
621
617
  }
622
- const resolvedPromise = Promise.resolve(promiseCreator({
623
- input: state.input
624
- }));
625
- resolvedPromise.then(response => {
626
- // TODO: remove this condition once dead letter queue lands
627
- if (self._state.status !== 'active') {
628
- return;
629
- }
630
- self.send({
631
- type: resolveEventType,
632
- data: response
633
- });
634
- }, errorData => {
635
- // TODO: remove this condition once dead letter queue lands
636
- if (self._state.status !== 'active') {
637
- return;
638
- }
639
- self.send({
640
- type: rejectEventType,
641
- data: errorData
642
- });
643
- });
644
618
  },
645
- getInitialState: (_, input) => {
646
- return {
647
- status: 'active',
648
- data: undefined,
649
- input
650
- };
619
+ get: systemId => {
620
+ return keyedActors.get(systemId);
651
621
  },
652
- getSnapshot: state => state.data,
653
- getStatus: state => state,
654
- getPersistedState: state => state,
655
- restoreState: state => state
622
+ _set: (systemId, actorRef) => {
623
+ const existing = keyedActors.get(systemId);
624
+ if (existing && existing !== actorRef) {
625
+ throw new Error(`Actor with system ID '${systemId}' already exists.`);
626
+ }
627
+ keyedActors.set(systemId, actorRef);
628
+ reverseKeyedActors.set(actorRef, systemId);
629
+ }
656
630
  };
657
- return behavior;
631
+ return system;
658
632
  }
659
633
 
660
- // TODO: this likely shouldn't accept TEvent, observable actor doesn't accept external events
661
- function fromObservable(observableCreator) {
662
- const nextEventType = '$$xstate.next';
663
- const errorEventType = '$$xstate.error';
664
- const completeEventType = '$$xstate.complete';
665
-
666
- // TODO: add event types
667
- const behavior = {
668
- config: observableCreator,
669
- transition: (state, event, {
670
- self,
671
- id,
672
- defer
673
- }) => {
674
- if (state.status !== 'active') {
675
- return state;
676
- }
677
- switch (event.type) {
678
- case nextEventType:
679
- // match the exact timing of events sent by machines
680
- // send actions are not executed immediately
681
- defer(() => {
682
- self._parent?.send({
683
- type: `xstate.snapshot.${id}`,
684
- data: event.data
685
- });
686
- });
687
- return {
688
- ...state,
689
- data: event.data
690
- };
691
- case errorEventType:
692
- return {
693
- ...state,
694
- status: 'error',
695
- input: undefined,
696
- data: event.data,
697
- subscription: undefined
698
- };
699
- case completeEventType:
700
- return {
701
- ...state,
702
- status: 'done',
703
- input: undefined,
704
- subscription: undefined
705
- };
706
- case stopSignalType:
707
- state.subscription.unsubscribe();
708
- return {
709
- ...state,
710
- status: 'canceled',
711
- input: undefined,
712
- subscription: undefined
713
- };
714
- default:
715
- return state;
716
- }
717
- },
718
- getInitialState: (_, input) => {
719
- return {
720
- subscription: undefined,
721
- status: 'active',
722
- data: undefined,
723
- input
724
- };
634
+ let ActorStatus = /*#__PURE__*/function (ActorStatus) {
635
+ ActorStatus[ActorStatus["NotStarted"] = 0] = "NotStarted";
636
+ ActorStatus[ActorStatus["Running"] = 1] = "Running";
637
+ ActorStatus[ActorStatus["Stopped"] = 2] = "Stopped";
638
+ return ActorStatus;
639
+ }({});
640
+ const defaultOptions = {
641
+ deferEvents: true,
642
+ clock: {
643
+ setTimeout: (fn, ms) => {
644
+ return setTimeout(fn, ms);
725
645
  },
726
- start: (state, {
727
- self
728
- }) => {
729
- if (state.status === 'done') {
730
- // Do not restart a completed observable
731
- return;
732
- }
733
- state.subscription = observableCreator({
734
- input: state.input
735
- }).subscribe({
736
- next: value => {
737
- self.send({
738
- type: nextEventType,
739
- data: value
740
- });
741
- },
742
- error: err => {
743
- self.send({
744
- type: errorEventType,
745
- data: err
746
- });
747
- },
748
- complete: () => {
749
- self.send({
750
- type: completeEventType
751
- });
752
- }
753
- });
754
- },
755
- getSnapshot: state => state.data,
756
- getPersistedState: ({
757
- status,
758
- data,
759
- input
760
- }) => ({
761
- status,
762
- data,
763
- input
764
- }),
765
- getStatus: state => state,
766
- restoreState: state => ({
767
- ...state,
768
- subscription: undefined
769
- })
770
- };
771
- return behavior;
772
- }
646
+ clearTimeout: id => {
647
+ return clearTimeout(id);
648
+ }
649
+ },
650
+ logger: console.log.bind(console),
651
+ devTools: false
652
+ };
653
+ class Interpreter {
654
+ /**
655
+ * The current state of the interpreted logic.
656
+ */
773
657
 
774
- /**
775
- * Creates an event observable behavior that listens to an observable
776
- * that delivers event objects.
777
- *
778
- *
779
- * @param lazyObservable A function that creates an observable
780
- * @returns An event observable behavior
781
- */
658
+ /**
659
+ * The clock that is responsible for setting and clearing timeouts, such as delayed events and transitions.
660
+ */
782
661
 
783
- function fromEventObservable(lazyObservable) {
784
- const errorEventType = '$$xstate.error';
785
- const completeEventType = '$$xstate.complete';
662
+ /**
663
+ * The unique identifier for this actor relative to its parent.
664
+ */
786
665
 
787
- // TODO: event types
788
- const behavior = {
789
- config: lazyObservable,
790
- transition: (state, event) => {
791
- if (state.status !== 'active') {
792
- return state;
793
- }
794
- switch (event.type) {
795
- case errorEventType:
796
- return {
797
- ...state,
798
- status: 'error',
799
- input: undefined,
800
- data: event.data,
801
- subscription: undefined
802
- };
803
- case completeEventType:
804
- return {
805
- ...state,
806
- status: 'done',
807
- input: undefined,
808
- subscription: undefined
809
- };
810
- case stopSignalType:
811
- state.subscription.unsubscribe();
812
- return {
813
- ...state,
814
- status: 'canceled',
815
- input: undefined,
816
- subscription: undefined
817
- };
818
- default:
819
- return state;
820
- }
821
- },
822
- getInitialState: (_, input) => {
823
- return {
824
- subscription: undefined,
825
- status: 'active',
826
- data: undefined,
827
- input
828
- };
829
- },
830
- start: (state, {
831
- self
832
- }) => {
833
- if (state.status === 'done') {
834
- // Do not restart a completed observable
835
- return;
836
- }
837
- state.subscription = lazyObservable({
838
- input: state.input
839
- }).subscribe({
840
- next: value => {
841
- self._parent?.send(value);
842
- },
843
- error: err => {
844
- self.send({
845
- type: errorEventType,
846
- data: err
847
- });
848
- },
849
- complete: () => {
850
- self.send({
851
- type: completeEventType
852
- });
853
- }
854
- });
855
- },
856
- getSnapshot: _ => undefined,
857
- getPersistedState: ({
858
- status,
859
- data,
860
- input
861
- }) => ({
862
- status,
863
- data,
864
- input
865
- }),
866
- getStatus: state => state,
867
- restoreState: state => ({
868
- ...state,
869
- subscription: undefined
870
- })
871
- };
872
- return behavior;
873
- }
666
+ /**
667
+ * Whether the service is started.
668
+ */
874
669
 
875
- function fromCallback(invokeCallback) {
876
- const behavior = {
877
- config: invokeCallback,
878
- start: (_state, {
879
- self
880
- }) => {
881
- self.send({
882
- type: startSignalType
883
- });
884
- },
885
- transition: (state, event, {
886
- self,
887
- id
888
- }) => {
889
- if (event.type === startSignalType) {
890
- const sender = eventForParent => {
891
- if (state.canceled) {
892
- return;
893
- }
894
- self._parent?.send(eventForParent);
895
- };
896
- const receiver = newListener => {
897
- state.receivers.add(newListener);
898
- };
899
- state.dispose = invokeCallback(sender, receiver, {
900
- input: state.input
901
- });
902
- if (isPromiseLike(state.dispose)) {
903
- state.dispose.then(resolved => {
904
- self._parent?.send(doneInvoke(id, resolved));
905
- state.canceled = true;
906
- }, errorData => {
907
- state.canceled = true;
908
- self._parent?.send(error(id, errorData));
909
- });
910
- }
911
- return state;
912
- }
913
- if (event.type === stopSignalType) {
914
- state.canceled = true;
915
- if (isFunction(state.dispose)) {
916
- state.dispose();
917
- }
918
- return state;
919
- }
920
- if (isSignal(event.type)) {
921
- // TODO: unrecognized signal
922
- return state;
923
- }
924
- if (!isSignal(event.type)) {
925
- state.receivers.forEach(receiver => receiver(event));
926
- }
927
- return state;
928
- },
929
- getInitialState: (_, input) => {
930
- return {
931
- canceled: false,
932
- receivers: new Set(),
933
- dispose: undefined,
934
- input
935
- };
936
- },
937
- getSnapshot: () => undefined,
938
- getPersistedState: ({
939
- input
940
- }) => input
941
- };
942
- return behavior;
943
- }
670
+ // Actor Ref
944
671
 
945
- const startSignalType = 'xstate.init';
946
- const stopSignalType = 'xstate.stop';
947
- const startSignal = {
948
- type: 'xstate.init'
949
- };
950
- const stopSignal = {
951
- type: 'xstate.stop'
952
- };
953
- /**
954
- * An object that expresses the behavior of an actor in reaction to received events,
955
- * as well as an optionally emitted stream of values.
956
- *
957
- * @template TReceived The received event
958
- * @template TSnapshot The emitted value
959
- */
672
+ // TODO: add typings for system
960
673
 
961
- function isSignal(eventType) {
962
- return eventType === startSignalType || eventType === stopSignalType;
963
- }
964
- function isActorRef(item) {
965
- return !!item && typeof item === 'object' && typeof item.send === 'function';
966
- }
967
-
968
- // TODO: refactor the return type, this could be written in a better way
969
- // but it's best to avoid unneccessary breaking changes now
970
- // @deprecated use `interpret(behavior)` instead
971
- function toActorRef(actorRefLike) {
972
- return {
973
- subscribe: () => ({
974
- unsubscribe: () => void 0
975
- }),
976
- id: 'anonymous',
977
- sessionId: '',
978
- getSnapshot: () => undefined,
979
- [symbolObservable]: function () {
980
- return this;
981
- },
982
- status: ActorStatus.Running,
983
- stop: () => void 0,
984
- ...actorRefLike
985
- };
986
- }
987
- const emptyBehavior = fromTransition(_ => undefined, undefined);
988
- function createEmptyActor() {
989
- return interpret(emptyBehavior);
990
- }
991
-
992
- function createSystem() {
993
- let sessionIdCounter = 0;
994
- const children = new Map();
995
- const keyedActors = new Map();
996
- const reverseKeyedActors = new WeakMap();
997
- const system = {
998
- _bookId: () => `x:${sessionIdCounter++}`,
999
- _register: (sessionId, actorRef) => {
1000
- children.set(sessionId, actorRef);
1001
- return sessionId;
1002
- },
1003
- _unregister: actorRef => {
1004
- children.delete(actorRef.sessionId);
1005
- const systemId = reverseKeyedActors.get(actorRef);
1006
- if (systemId !== undefined) {
1007
- keyedActors.delete(systemId);
1008
- reverseKeyedActors.delete(actorRef);
1009
- }
1010
- },
1011
- get: systemId => {
1012
- return keyedActors.get(systemId);
1013
- },
1014
- _set: (systemId, actorRef) => {
1015
- const existing = keyedActors.get(systemId);
1016
- if (existing && existing !== actorRef) {
1017
- throw new Error(`Actor with system ID '${systemId}' already exists.`);
1018
- }
1019
- keyedActors.set(systemId, actorRef);
1020
- reverseKeyedActors.set(actorRef, systemId);
1021
- }
1022
- };
1023
- return system;
1024
- }
1025
-
1026
- let ActorStatus = /*#__PURE__*/function (ActorStatus) {
1027
- ActorStatus[ActorStatus["NotStarted"] = 0] = "NotStarted";
1028
- ActorStatus[ActorStatus["Running"] = 1] = "Running";
1029
- ActorStatus[ActorStatus["Stopped"] = 2] = "Stopped";
1030
- return ActorStatus;
1031
- }({});
1032
- const defaultOptions = {
1033
- deferEvents: true,
1034
- clock: {
1035
- setTimeout: (fn, ms) => {
1036
- return setTimeout(fn, ms);
1037
- },
1038
- clearTimeout: id => {
1039
- return clearTimeout(id);
1040
- }
1041
- },
1042
- logger: console.log.bind(console),
1043
- devTools: false
1044
- };
1045
- class Interpreter {
1046
- /**
1047
- * The current state of the interpreted behavior.
1048
- */
1049
-
1050
- /**
1051
- * The clock that is responsible for setting and clearing timeouts, such as delayed events and transitions.
1052
- */
1053
-
1054
- /**
1055
- * The unique identifier for this actor relative to its parent.
1056
- */
674
+ /**
675
+ * The globally unique process ID for this invocation.
676
+ */
1057
677
 
1058
678
  /**
1059
- * Whether the service is started.
1060
- */
1061
-
1062
- // Actor Ref
1063
-
1064
- // TODO: add typings for system
1065
-
1066
- /**
1067
- * The globally unique process ID for this invocation.
1068
- */
1069
-
1070
- /**
1071
- * Creates a new Interpreter instance (i.e., service) for the given behavior with the provided options, if any.
679
+ * Creates a new Interpreter instance (i.e., service) for the given logic with the provided options, if any.
1072
680
  *
1073
- * @param behavior The behavior to be interpreted
681
+ * @param logic The logic to be interpreted
1074
682
  * @param options Interpreter options
1075
683
  */
1076
- constructor(behavior, options) {
1077
- this.behavior = behavior;
684
+ constructor(logic, options) {
685
+ this.logic = logic;
1078
686
  this._state = void 0;
1079
687
  this.clock = void 0;
1080
688
  this.options = void 0;
@@ -1141,7 +749,7 @@ class Interpreter {
1141
749
  this._initState();
1142
750
  }
1143
751
  _initState() {
1144
- this._state = this.options.state ? this.behavior.restoreState ? this.behavior.restoreState(this.options.state, this._actorContext) : this.options.state : this.behavior.getInitialState(this._actorContext, this.options?.input);
752
+ this._state = this.options.state ? this.logic.restoreState ? this.logic.restoreState(this.options.state, this._actorContext) : this.options.state : this.logic.getInitialState(this._actorContext, this.options?.input);
1145
753
  }
1146
754
 
1147
755
  // array of functions to defer
@@ -1154,12 +762,12 @@ class Interpreter {
1154
762
  // Execute deferred effects
1155
763
  let deferredFn;
1156
764
  while (deferredFn = this._deferred.shift()) {
1157
- deferredFn(state);
765
+ deferredFn();
1158
766
  }
1159
767
  for (const observer of this.observers) {
1160
768
  observer.next?.(snapshot);
1161
769
  }
1162
- const status = this.behavior.getStatus?.(state);
770
+ const status = this.logic.getStatus?.(state);
1163
771
  switch (status?.status) {
1164
772
  case 'done':
1165
773
  this._stopProcedure();
@@ -1201,8 +809,8 @@ class Interpreter {
1201
809
  this.system._set(this._systemId, this);
1202
810
  }
1203
811
  this.status = ActorStatus.Running;
1204
- if (this.behavior.start) {
1205
- this.behavior.start(this._state, this._actorContext);
812
+ if (this.logic.start) {
813
+ this.logic.start(this._state, this._actorContext);
1206
814
  }
1207
815
 
1208
816
  // TODO: this notifies all subscribers but usually this is redundant
@@ -1217,7 +825,7 @@ class Interpreter {
1217
825
  }
1218
826
  _process(event) {
1219
827
  try {
1220
- const nextState = this.behavior.transition(this._state, event, this._actorContext);
828
+ const nextState = this.logic.transition(this._state, event, this._actorContext);
1221
829
  this.update(nextState);
1222
830
  if (event.type === stopSignalType) {
1223
831
  this._stopProcedure();
@@ -1309,211 +917,604 @@ class Interpreter {
1309
917
  const eventString = JSON.stringify(event);
1310
918
  console.warn(`Event "${event.type.toString()}" was sent to stopped actor "${this.id} (${this.sessionId})". This actor has already reached its final state, and will not transition.\nEvent: ${eventString}`);
1311
919
  }
1312
- return;
1313
- }
1314
- if (this.status !== ActorStatus.Running && !this.options.deferEvents) {
1315
- throw new Error(`Event "${event.type}" was sent to uninitialized actor "${this.id
1316
- // tslint:disable-next-line:max-line-length
1317
- }". Make sure .start() is called for this actor, or set { deferEvents: true } in the actor options.\nEvent: ${JSON.stringify(event)}`);
1318
- }
1319
- this.mailbox.enqueue(event);
1320
- }
1321
-
1322
- // TODO: make private (and figure out a way to do this within the machine)
1323
- delaySend(sendAction) {
1324
- this.delayedEventsMap[sendAction.params.id] = this.clock.setTimeout(() => {
1325
- if ('to' in sendAction.params && sendAction.params.to) {
1326
- sendAction.params.to.send(sendAction.params.event);
1327
- } else {
1328
- this.send(sendAction.params.event);
920
+ return;
921
+ }
922
+ if (this.status !== ActorStatus.Running && !this.options.deferEvents) {
923
+ throw new Error(`Event "${event.type}" was sent to uninitialized actor "${this.id
924
+ // tslint:disable-next-line:max-line-length
925
+ }". Make sure .start() is called for this actor, or set { deferEvents: true } in the actor options.\nEvent: ${JSON.stringify(event)}`);
926
+ }
927
+ this.mailbox.enqueue(event);
928
+ }
929
+
930
+ // TODO: make private (and figure out a way to do this within the machine)
931
+ delaySend(sendAction) {
932
+ this.delayedEventsMap[sendAction.params.id] = this.clock.setTimeout(() => {
933
+ if ('to' in sendAction.params && sendAction.params.to) {
934
+ sendAction.params.to.send(sendAction.params.event);
935
+ } else {
936
+ this.send(sendAction.params.event);
937
+ }
938
+ }, sendAction.params.delay);
939
+ }
940
+
941
+ // TODO: make private (and figure out a way to do this within the machine)
942
+ cancel(sendId) {
943
+ this.clock.clearTimeout(this.delayedEventsMap[sendId]);
944
+ delete this.delayedEventsMap[sendId];
945
+ }
946
+ attachDevTools() {
947
+ const {
948
+ devTools
949
+ } = this.options;
950
+ if (devTools) {
951
+ const resolvedDevToolsAdapter = typeof devTools === 'function' ? devTools : devToolsAdapter;
952
+ resolvedDevToolsAdapter(this);
953
+ }
954
+ }
955
+ toJSON() {
956
+ return {
957
+ id: this.id
958
+ };
959
+ }
960
+ getPersistedState() {
961
+ return this.logic.getPersistedState?.(this._state);
962
+ }
963
+ [symbolObservable]() {
964
+ return this;
965
+ }
966
+ getSnapshot() {
967
+ return this.logic.getSnapshot ? this.logic.getSnapshot(this._state) : this._state;
968
+ }
969
+ }
970
+
971
+ /**
972
+ * Creates a new Interpreter instance for the given machine with the provided options, if any.
973
+ *
974
+ * @param machine The machine to interpret
975
+ * @param options Interpreter options
976
+ */
977
+
978
+ function interpret(logic, options) {
979
+ const interpreter = new Interpreter(logic, options);
980
+ return interpreter;
981
+ }
982
+
983
+ /**
984
+ * Returns actor logic from a transition function and its initial state.
985
+ *
986
+ * A transition function is a function that takes the current state and an event and returns the next state.
987
+ *
988
+ * @param transition The transition function that returns the next state given the current state and event.
989
+ * @param initialState The initial state of the transition function.
990
+ * @returns Actor logic
991
+ */
992
+ function fromTransition(transition, initialState) {
993
+ const logic = {
994
+ config: transition,
995
+ transition: (state, event, actorContext) => {
996
+ return transition(state, event, actorContext);
997
+ },
998
+ getInitialState: (_, input) => {
999
+ return typeof initialState === 'function' ? initialState({
1000
+ input
1001
+ }) : initialState;
1002
+ },
1003
+ getSnapshot: state => state,
1004
+ getPersistedState: state => state,
1005
+ restoreState: state => state
1006
+ };
1007
+ return logic;
1008
+ }
1009
+
1010
+ function fromPromise(
1011
+ // TODO: add types
1012
+ promiseCreator) {
1013
+ const resolveEventType = '$$xstate.resolve';
1014
+ const rejectEventType = '$$xstate.reject';
1015
+
1016
+ // TODO: add event types
1017
+ const logic = {
1018
+ config: promiseCreator,
1019
+ transition: (state, event) => {
1020
+ if (state.status !== 'active') {
1021
+ return state;
1022
+ }
1023
+ switch (event.type) {
1024
+ case resolveEventType:
1025
+ return {
1026
+ ...state,
1027
+ status: 'done',
1028
+ data: event.data,
1029
+ input: undefined
1030
+ };
1031
+ case rejectEventType:
1032
+ return {
1033
+ ...state,
1034
+ status: 'error',
1035
+ data: event.data,
1036
+ input: undefined
1037
+ };
1038
+ case stopSignalType:
1039
+ return {
1040
+ ...state,
1041
+ status: 'canceled',
1042
+ input: undefined
1043
+ };
1044
+ default:
1045
+ return state;
1046
+ }
1047
+ },
1048
+ start: (state, {
1049
+ self,
1050
+ system
1051
+ }) => {
1052
+ // TODO: determine how to allow customizing this so that promises
1053
+ // can be restarted if necessary
1054
+ if (state.status !== 'active') {
1055
+ return;
1056
+ }
1057
+ const resolvedPromise = Promise.resolve(promiseCreator({
1058
+ input: state.input,
1059
+ system
1060
+ }));
1061
+ resolvedPromise.then(response => {
1062
+ // TODO: remove this condition once dead letter queue lands
1063
+ if (self._state.status !== 'active') {
1064
+ return;
1065
+ }
1066
+ self.send({
1067
+ type: resolveEventType,
1068
+ data: response
1069
+ });
1070
+ }, errorData => {
1071
+ // TODO: remove this condition once dead letter queue lands
1072
+ if (self._state.status !== 'active') {
1073
+ return;
1074
+ }
1075
+ self.send({
1076
+ type: rejectEventType,
1077
+ data: errorData
1078
+ });
1079
+ });
1080
+ },
1081
+ getInitialState: (_, input) => {
1082
+ return {
1083
+ status: 'active',
1084
+ data: undefined,
1085
+ input
1086
+ };
1087
+ },
1088
+ getSnapshot: state => state.data,
1089
+ getStatus: state => state,
1090
+ getPersistedState: state => state,
1091
+ restoreState: state => state
1092
+ };
1093
+ return logic;
1094
+ }
1095
+
1096
+ // TODO: this likely shouldn't accept TEvent, observable actor doesn't accept external events
1097
+ function fromObservable(observableCreator) {
1098
+ const nextEventType = '$$xstate.next';
1099
+ const errorEventType = '$$xstate.error';
1100
+ const completeEventType = '$$xstate.complete';
1101
+
1102
+ // TODO: add event types
1103
+ const logic = {
1104
+ config: observableCreator,
1105
+ transition: (state, event, {
1106
+ self,
1107
+ id,
1108
+ defer
1109
+ }) => {
1110
+ if (state.status !== 'active') {
1111
+ return state;
1112
+ }
1113
+ switch (event.type) {
1114
+ case nextEventType:
1115
+ // match the exact timing of events sent by machines
1116
+ // send actions are not executed immediately
1117
+ defer(() => {
1118
+ self._parent?.send({
1119
+ type: `xstate.snapshot.${id}`,
1120
+ data: event.data
1121
+ });
1122
+ });
1123
+ return {
1124
+ ...state,
1125
+ data: event.data
1126
+ };
1127
+ case errorEventType:
1128
+ return {
1129
+ ...state,
1130
+ status: 'error',
1131
+ input: undefined,
1132
+ data: event.data,
1133
+ subscription: undefined
1134
+ };
1135
+ case completeEventType:
1136
+ return {
1137
+ ...state,
1138
+ status: 'done',
1139
+ input: undefined,
1140
+ subscription: undefined
1141
+ };
1142
+ case stopSignalType:
1143
+ state.subscription.unsubscribe();
1144
+ return {
1145
+ ...state,
1146
+ status: 'canceled',
1147
+ input: undefined,
1148
+ subscription: undefined
1149
+ };
1150
+ default:
1151
+ return state;
1152
+ }
1153
+ },
1154
+ getInitialState: (_, input) => {
1155
+ return {
1156
+ subscription: undefined,
1157
+ status: 'active',
1158
+ data: undefined,
1159
+ input
1160
+ };
1161
+ },
1162
+ start: (state, {
1163
+ self,
1164
+ system
1165
+ }) => {
1166
+ if (state.status === 'done') {
1167
+ // Do not restart a completed observable
1168
+ return;
1169
+ }
1170
+ state.subscription = observableCreator({
1171
+ input: state.input,
1172
+ system
1173
+ }).subscribe({
1174
+ next: value => {
1175
+ self.send({
1176
+ type: nextEventType,
1177
+ data: value
1178
+ });
1179
+ },
1180
+ error: err => {
1181
+ self.send({
1182
+ type: errorEventType,
1183
+ data: err
1184
+ });
1185
+ },
1186
+ complete: () => {
1187
+ self.send({
1188
+ type: completeEventType
1189
+ });
1190
+ }
1191
+ });
1192
+ },
1193
+ getSnapshot: state => state.data,
1194
+ getPersistedState: ({
1195
+ status,
1196
+ data,
1197
+ input
1198
+ }) => ({
1199
+ status,
1200
+ data,
1201
+ input
1202
+ }),
1203
+ getStatus: state => state,
1204
+ restoreState: state => ({
1205
+ ...state,
1206
+ subscription: undefined
1207
+ })
1208
+ };
1209
+ return logic;
1210
+ }
1211
+
1212
+ /**
1213
+ * Creates event observable logic that listens to an observable
1214
+ * that delivers event objects.
1215
+ *
1216
+ *
1217
+ * @param lazyObservable A function that creates an observable
1218
+ * @returns Event observable logic
1219
+ */
1220
+
1221
+ function fromEventObservable(lazyObservable) {
1222
+ const errorEventType = '$$xstate.error';
1223
+ const completeEventType = '$$xstate.complete';
1224
+
1225
+ // TODO: event types
1226
+ const logic = {
1227
+ config: lazyObservable,
1228
+ transition: (state, event) => {
1229
+ if (state.status !== 'active') {
1230
+ return state;
1231
+ }
1232
+ switch (event.type) {
1233
+ case errorEventType:
1234
+ return {
1235
+ ...state,
1236
+ status: 'error',
1237
+ input: undefined,
1238
+ data: event.data,
1239
+ subscription: undefined
1240
+ };
1241
+ case completeEventType:
1242
+ return {
1243
+ ...state,
1244
+ status: 'done',
1245
+ input: undefined,
1246
+ subscription: undefined
1247
+ };
1248
+ case stopSignalType:
1249
+ state.subscription.unsubscribe();
1250
+ return {
1251
+ ...state,
1252
+ status: 'canceled',
1253
+ input: undefined,
1254
+ subscription: undefined
1255
+ };
1256
+ default:
1257
+ return state;
1258
+ }
1259
+ },
1260
+ getInitialState: (_, input) => {
1261
+ return {
1262
+ subscription: undefined,
1263
+ status: 'active',
1264
+ data: undefined,
1265
+ input
1266
+ };
1267
+ },
1268
+ start: (state, {
1269
+ self,
1270
+ system
1271
+ }) => {
1272
+ if (state.status === 'done') {
1273
+ // Do not restart a completed observable
1274
+ return;
1275
+ }
1276
+ state.subscription = lazyObservable({
1277
+ input: state.input,
1278
+ system
1279
+ }).subscribe({
1280
+ next: value => {
1281
+ self._parent?.send(value);
1282
+ },
1283
+ error: err => {
1284
+ self.send({
1285
+ type: errorEventType,
1286
+ data: err
1287
+ });
1288
+ },
1289
+ complete: () => {
1290
+ self.send({
1291
+ type: completeEventType
1292
+ });
1293
+ }
1294
+ });
1295
+ },
1296
+ getSnapshot: _ => undefined,
1297
+ getPersistedState: ({
1298
+ status,
1299
+ data,
1300
+ input
1301
+ }) => ({
1302
+ status,
1303
+ data,
1304
+ input
1305
+ }),
1306
+ getStatus: state => state,
1307
+ restoreState: state => ({
1308
+ ...state,
1309
+ subscription: undefined
1310
+ })
1311
+ };
1312
+ return logic;
1313
+ }
1314
+
1315
+ function fromCallback(invokeCallback) {
1316
+ const logic = {
1317
+ config: invokeCallback,
1318
+ start: (_state, {
1319
+ self
1320
+ }) => {
1321
+ self.send({
1322
+ type: startSignalType
1323
+ });
1324
+ },
1325
+ transition: (state, event, {
1326
+ self,
1327
+ id,
1328
+ system
1329
+ }) => {
1330
+ if (event.type === startSignalType) {
1331
+ const sender = eventForParent => {
1332
+ if (state.canceled) {
1333
+ return;
1334
+ }
1335
+ self._parent?.send(eventForParent);
1336
+ };
1337
+ const receiver = newListener => {
1338
+ state.receivers.add(newListener);
1339
+ };
1340
+ state.dispose = invokeCallback(sender, receiver, {
1341
+ input: state.input,
1342
+ system
1343
+ });
1344
+ if (isPromiseLike(state.dispose)) {
1345
+ state.dispose.then(resolved => {
1346
+ self._parent?.send(doneInvoke(id, resolved));
1347
+ state.canceled = true;
1348
+ }, errorData => {
1349
+ state.canceled = true;
1350
+ self._parent?.send(error(id, errorData));
1351
+ });
1352
+ }
1353
+ return state;
1354
+ }
1355
+ if (event.type === stopSignalType) {
1356
+ state.canceled = true;
1357
+ if (isFunction(state.dispose)) {
1358
+ state.dispose();
1359
+ }
1360
+ return state;
1329
1361
  }
1330
- }, sendAction.params.delay);
1331
- }
1332
-
1333
- // TODO: make private (and figure out a way to do this within the machine)
1334
- cancel(sendId) {
1335
- this.clock.clearTimeout(this.delayedEventsMap[sendId]);
1336
- delete this.delayedEventsMap[sendId];
1337
- }
1338
- attachDevTools() {
1339
- const {
1340
- devTools
1341
- } = this.options;
1342
- if (devTools) {
1343
- const resolvedDevToolsAdapter = typeof devTools === 'function' ? devTools : devToolsAdapter;
1344
- resolvedDevToolsAdapter(this);
1345
- }
1346
- }
1347
- toJSON() {
1348
- return {
1349
- id: this.id
1350
- };
1351
- }
1352
- getPersistedState() {
1353
- return this.behavior.getPersistedState?.(this._state);
1354
- }
1355
- [symbolObservable]() {
1356
- return this;
1357
- }
1358
- getSnapshot() {
1359
- return this.behavior.getSnapshot ? this.behavior.getSnapshot(this._state) : this._state;
1360
- }
1362
+ if (isSignal(event.type)) {
1363
+ // TODO: unrecognized signal
1364
+ return state;
1365
+ }
1366
+ if (!isSignal(event.type)) {
1367
+ state.receivers.forEach(receiver => receiver(event));
1368
+ }
1369
+ return state;
1370
+ },
1371
+ getInitialState: (_, input) => {
1372
+ return {
1373
+ canceled: false,
1374
+ receivers: new Set(),
1375
+ dispose: undefined,
1376
+ input
1377
+ };
1378
+ },
1379
+ getSnapshot: () => undefined,
1380
+ getPersistedState: ({
1381
+ input
1382
+ }) => input
1383
+ };
1384
+ return logic;
1361
1385
  }
1362
1386
 
1387
+ const startSignalType = 'xstate.init';
1388
+ const stopSignalType = 'xstate.stop';
1389
+ const startSignal = {
1390
+ type: 'xstate.init'
1391
+ };
1392
+ const stopSignal = {
1393
+ type: 'xstate.stop'
1394
+ };
1363
1395
  /**
1364
- * Creates a new Interpreter instance for the given machine with the provided options, if any.
1396
+ * An object that expresses the actor logic in reaction to received events,
1397
+ * as well as an optionally emitted stream of values.
1365
1398
  *
1366
- * @param machine The machine to interpret
1367
- * @param options Interpreter options
1399
+ * @template TReceived The received event
1400
+ * @template TSnapshot The emitted value
1368
1401
  */
1369
1402
 
1370
- function interpret(behavior, options) {
1371
- const interpreter = new Interpreter(behavior, options);
1372
- return interpreter;
1403
+ function isSignal(eventType) {
1404
+ return eventType === startSignalType || eventType === stopSignalType;
1373
1405
  }
1374
-
1375
- /**
1376
- * Stops an actor.
1377
- *
1378
- * @param actorRef The actor to stop.
1379
- */
1380
-
1381
- function stop(actorRef) {
1382
- const actor = actorRef;
1383
- return createDynamicAction({
1384
- type: stop$1,
1385
- params: {
1386
- actor
1387
- }
1388
- }, (event, {
1389
- state
1390
- }) => {
1391
- const actorRefOrString = isFunction(actor) ? actor({
1392
- context: state.context,
1393
- event
1394
- }) : actor;
1395
- const actorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
1396
- return [state, {
1397
- type: 'xstate.stop',
1398
- params: {
1399
- actor: actorRef
1400
- },
1401
- execute: actorCtx => {
1402
- if (!actorRef) {
1403
- return;
1404
- }
1405
- if (actorRef.status !== ActorStatus.Running) {
1406
- actorCtx.stopChild(actorRef);
1407
- return;
1408
- }
1409
- actorCtx.defer(() => {
1410
- actorCtx.stopChild(actorRef);
1411
- });
1412
- }
1413
- }];
1414
- });
1406
+ function isActorRef(item) {
1407
+ return !!item && typeof item === 'object' && typeof item.send === 'function';
1415
1408
  }
1416
1409
 
1417
- const defaultLogExpr = ({
1418
- context,
1419
- event
1420
- }) => ({
1421
- context,
1422
- event
1423
- });
1424
-
1425
- /**
1426
- *
1427
- * @param expr The expression function to evaluate which will be logged.
1428
- * Takes in 2 arguments:
1429
- * - `ctx` - the current state context
1430
- * - `event` - the event that caused this action to be executed.
1431
- * @param label The label to give to the logged expression.
1432
- */
1410
+ // TODO: refactor the return type, this could be written in a better way
1411
+ // but it's best to avoid unneccessary breaking changes now
1412
+ // @deprecated use `interpret(actorLogic)` instead
1413
+ function toActorRef(actorRefLike) {
1414
+ return {
1415
+ subscribe: () => ({
1416
+ unsubscribe: () => void 0
1417
+ }),
1418
+ id: 'anonymous',
1419
+ sessionId: '',
1420
+ getSnapshot: () => undefined,
1421
+ [symbolObservable]: function () {
1422
+ return this;
1423
+ },
1424
+ status: ActorStatus.Running,
1425
+ stop: () => void 0,
1426
+ ...actorRefLike
1427
+ };
1428
+ }
1429
+ const emptyLogic = fromTransition(_ => undefined, undefined);
1430
+ function createEmptyActor() {
1431
+ return interpret(emptyLogic);
1432
+ }
1433
1433
 
1434
- function log(expr = defaultLogExpr, label) {
1434
+ function invoke(invokeDef) {
1435
1435
  return createDynamicAction({
1436
- type: log$1,
1437
- params: {
1438
- label,
1439
- expr
1440
- }
1436
+ type: invoke$1,
1437
+ params: invokeDef
1441
1438
  }, (event, {
1442
1439
  state,
1443
1440
  actorContext
1444
1441
  }) => {
1445
- const resolvedValue = typeof expr === 'function' ? expr({
1446
- context: state.context,
1447
- event,
1448
- self: actorContext?.self ?? {},
1449
- system: actorContext?.system
1450
- }) : expr;
1451
- return [state, {
1452
- type: 'xstate.log',
1453
- params: {
1454
- label,
1455
- value: resolvedValue
1456
- },
1457
- execute: actorCtx => {
1458
- if (label) {
1459
- actorCtx.logger?.(label, resolvedValue);
1460
- } else {
1461
- actorCtx.logger?.(resolvedValue);
1442
+ const type = invoke$1;
1443
+ const {
1444
+ id,
1445
+ src
1446
+ } = invokeDef;
1447
+ let resolvedInvokeAction;
1448
+ if (isActorRef(src)) {
1449
+ resolvedInvokeAction = {
1450
+ type,
1451
+ params: {
1452
+ ...invokeDef,
1453
+ ref: src
1462
1454
  }
1463
- }
1464
- }];
1465
- });
1466
- }
1467
-
1468
- /**
1469
- * Cancels an in-flight `send(...)` action. A canceled sent action will not
1470
- * be executed, nor will its event be sent, unless it has already been sent
1471
- * (e.g., if `cancel(...)` is called after the `send(...)` action's `delay`).
1472
- *
1473
- * @param sendId The `id` of the `send(...)` action to cancel.
1474
- */
1475
-
1476
- function cancel(sendId) {
1477
- return createDynamicAction({
1478
- type: cancel$1,
1479
- params: {
1480
- sendId
1455
+ };
1456
+ } else {
1457
+ const referenced = resolveReferencedActor(state.machine.options.actors[src]);
1458
+ if (!referenced) {
1459
+ resolvedInvokeAction = {
1460
+ type,
1461
+ params: invokeDef
1462
+ };
1463
+ } else {
1464
+ const input = 'input' in invokeDef ? invokeDef.input : referenced.input;
1465
+ const ref = interpret(referenced.src, {
1466
+ id,
1467
+ src,
1468
+ parent: actorContext?.self,
1469
+ systemId: invokeDef.systemId,
1470
+ input: typeof input === 'function' ? input({
1471
+ context: state.context,
1472
+ event,
1473
+ self: actorContext?.self
1474
+ }) : input
1475
+ });
1476
+ resolvedInvokeAction = {
1477
+ type,
1478
+ params: {
1479
+ ...invokeDef,
1480
+ ref
1481
+ }
1482
+ };
1483
+ }
1481
1484
  }
1482
- }, (event, {
1483
- state,
1484
- actorContext
1485
- }) => {
1486
- const resolvedSendId = isFunction(sendId) ? sendId({
1487
- context: state.context,
1488
- event,
1489
- self: actorContext?.self ?? {},
1490
- system: actorContext?.system
1491
- }) : sendId;
1492
- return [state, {
1493
- type: 'xstate.cancel',
1494
- params: {
1495
- sendId: resolvedSendId
1496
- },
1497
- execute: actorCtx => {
1498
- const interpreter = actorCtx.self;
1499
- interpreter.cancel(resolvedSendId);
1485
+ const actorRef = resolvedInvokeAction.params.ref;
1486
+ const invokedState = cloneState(state, {
1487
+ children: {
1488
+ ...state.children,
1489
+ [id]: actorRef
1500
1490
  }
1501
- }];
1502
- });
1503
- }
1504
-
1505
- const cache = new WeakMap();
1506
- function memo(object, key, fn) {
1507
- let memoizedData = cache.get(object);
1508
- if (!memoizedData) {
1509
- memoizedData = {
1510
- [key]: fn()
1491
+ });
1492
+ resolvedInvokeAction.execute = actorCtx => {
1493
+ const parent = actorCtx.self;
1494
+ const {
1495
+ id,
1496
+ ref
1497
+ } = resolvedInvokeAction.params;
1498
+ if (!ref) {
1499
+ {
1500
+ console.warn(`Actor type '${resolvedInvokeAction.params.src}' not found in machine '${actorCtx.id}'.`);
1501
+ }
1502
+ return;
1503
+ }
1504
+ actorCtx.defer(() => {
1505
+ if (actorRef.status === ActorStatus.Stopped) {
1506
+ return;
1507
+ }
1508
+ try {
1509
+ actorRef.start?.();
1510
+ } catch (err) {
1511
+ parent.send(error(id, err));
1512
+ return;
1513
+ }
1514
+ });
1511
1515
  };
1512
- cache.set(object, memoizedData);
1513
- } else if (!(key in memoizedData)) {
1514
- memoizedData[key] = fn();
1515
- }
1516
- return memoizedData[key];
1516
+ return [invokedState, resolvedInvokeAction];
1517
+ });
1517
1518
  }
1518
1519
 
1519
1520
  function stateIn(stateValue) {
@@ -2256,15 +2257,11 @@ function microstep(transitions, currentState, actorCtx, event) {
2256
2257
  const willTransition = currentState._initial || transitions.length > 0;
2257
2258
  const mutConfiguration = new Set(currentState.configuration);
2258
2259
  if (!currentState._initial && !willTransition) {
2259
- const inertState = cloneState(currentState, {
2260
- event,
2261
- actions: [],
2262
- transitions: []
2263
- });
2260
+ const inertState = cloneState(currentState, {});
2264
2261
  inertState.changed = false;
2265
2262
  return inertState;
2266
2263
  }
2267
- const microstate = microstepProcedure(currentState._initial ? [{
2264
+ const [microstate, actions] = microstepProcedure(currentState._initial ? [{
2268
2265
  target: [...currentState.configuration].filter(isAtomicStateNode),
2269
2266
  source: machine.root,
2270
2267
  reenter: true,
@@ -2273,38 +2270,16 @@ function microstep(transitions, currentState, actorCtx, event) {
2273
2270
  toJSON: null // TODO: fix
2274
2271
  }] : transitions, currentState, mutConfiguration, event, actorCtx);
2275
2272
  const {
2276
- context,
2277
- actions: nonRaisedActions
2273
+ context
2278
2274
  } = microstate;
2279
- const children = setChildren(currentState, nonRaisedActions);
2280
2275
  const nextState = cloneState(microstate, {
2281
2276
  value: {},
2282
2277
  // TODO: make optional
2283
- transitions,
2284
- children
2278
+ transitions
2285
2279
  });
2286
- nextState.changed = currentState._initial ? undefined : !stateValuesEqual(nextState.value, currentState.value) || nextState.actions.length > 0 || context !== currentState.context;
2280
+ nextState.changed = currentState._initial ? undefined : !stateValuesEqual(nextState.value, currentState.value) || actions.length > 0 || context !== currentState.context;
2287
2281
  return nextState;
2288
2282
  }
2289
- function setChildren(currentState, nonRaisedActions) {
2290
- const children = {
2291
- ...currentState.children
2292
- };
2293
- for (const action of nonRaisedActions) {
2294
- if (action.type === invoke$1 && action.params.ref) {
2295
- const ref = action.params.ref;
2296
- if (ref) {
2297
- children[ref.id] = ref;
2298
- }
2299
- } else if (action.type === stop$1) {
2300
- const ref = action.params.actor;
2301
- if (ref) {
2302
- delete children[ref.id];
2303
- }
2304
- }
2305
- }
2306
- return children;
2307
- }
2308
2283
  function microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx) {
2309
2284
  const actions = [];
2310
2285
  const historyValue = {
@@ -2322,7 +2297,7 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
2322
2297
  actions.push(...filteredTransitions.flatMap(t => t.actions));
2323
2298
 
2324
2299
  // Enter states
2325
- enterStates(filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue);
2300
+ enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue);
2326
2301
  const nextConfiguration = [...mutConfiguration];
2327
2302
  const done = isInFinalState(nextConfiguration);
2328
2303
  if (done) {
@@ -2330,29 +2305,25 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
2330
2305
  actions.push(...finalActions);
2331
2306
  }
2332
2307
  try {
2333
- const {
2334
- nextState
2335
- } = resolveActionsAndContext(actions, event, currentState, actorCtx);
2308
+ const [nextState, resolvedActions] = resolveActionsAndContext(actions, event, currentState, actorCtx);
2336
2309
  const output = done ? getOutput(nextConfiguration, nextState.context, event) : undefined;
2337
2310
  internalQueue.push(...nextState._internalQueue);
2338
- return cloneState(currentState, {
2339
- actions: nextState.actions,
2311
+ return [cloneState(currentState, {
2340
2312
  configuration: nextConfiguration,
2341
2313
  historyValue,
2342
2314
  _internalQueue: internalQueue,
2343
2315
  context: nextState.context,
2344
- event,
2345
2316
  done,
2346
2317
  output,
2347
2318
  children: nextState.children
2348
- });
2319
+ }), resolvedActions];
2349
2320
  } catch (e) {
2350
2321
  // TODO: Refactor this once proper error handling is implemented.
2351
2322
  // See https://github.com/statelyai/rfcs/pull/4
2352
2323
  throw e;
2353
2324
  }
2354
2325
  }
2355
- function enterStates(filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue) {
2326
+ function enterStates(event, filteredTransitions, mutConfiguration, actions, internalQueue, currentState, historyValue) {
2356
2327
  const statesToEnter = new Set();
2357
2328
  const statesForDefaultEntry = new Set();
2358
2329
  computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
@@ -2380,7 +2351,7 @@ function enterStates(filteredTransitions, mutConfiguration, actions, internalQue
2380
2351
  if (!parent.parent) {
2381
2352
  continue;
2382
2353
  }
2383
- internalQueue.push(done(parent.id, stateNodeToEnter.output ? mapContext(stateNodeToEnter.output, currentState.context, currentState.event) : undefined));
2354
+ internalQueue.push(done(parent.id, stateNodeToEnter.output ? mapContext(stateNodeToEnter.output, currentState.context, event) : undefined));
2384
2355
  if (parent.parent) {
2385
2356
  const grandparent = parent.parent;
2386
2357
  if (grandparent.type === 'parallel') {
@@ -2498,8 +2469,8 @@ function resolveActionsAndContext(actions, event, currentState, actorCtx) {
2498
2469
  resolvedActions.push(action);
2499
2470
  if (actorCtx?.self.status === ActorStatus.Running) {
2500
2471
  action.execute?.(actorCtx);
2501
- // TODO: this is hacky; re-evaluate
2502
- delete action.execute;
2472
+ } else {
2473
+ actorCtx?.defer(() => action.execute?.(actorCtx));
2503
2474
  }
2504
2475
  }
2505
2476
  function resolveAction(actionObject) {
@@ -2528,12 +2499,9 @@ function resolveActionsAndContext(actions, event, currentState, actorCtx) {
2528
2499
  for (const actionObject of actions) {
2529
2500
  resolveAction(actionObject);
2530
2501
  }
2531
- return {
2532
- nextState: cloneState(intermediateState, {
2533
- actions: resolvedActions,
2534
- _internalQueue: raiseActions.map(a => a.params.event)
2535
- })
2536
- };
2502
+ return [cloneState(intermediateState, {
2503
+ _internalQueue: raiseActions.map(a => a.params.event)
2504
+ }), resolvedActions];
2537
2505
  }
2538
2506
  function macrostep(state, event, actorCtx) {
2539
2507
  if (event.type === WILDCARD) {
@@ -2544,54 +2512,42 @@ function macrostep(state, event, actorCtx) {
2544
2512
 
2545
2513
  // Handle stop event
2546
2514
  if (event.type === stopSignalType) {
2547
- nextState = stopStep(event, nextState, actorCtx);
2515
+ nextState = stopStep(event, nextState, actorCtx)[0];
2548
2516
  states.push(nextState);
2549
2517
  return {
2550
2518
  state: nextState,
2551
2519
  microstates: states
2552
2520
  };
2553
2521
  }
2522
+ let nextEvent = event;
2554
2523
 
2555
2524
  // Assume the state is at rest (no raised events)
2556
2525
  // Determine the next state based on the next microstep
2557
- if (event.type !== init) {
2558
- const transitions = selectTransitions(event, nextState);
2559
- nextState = microstep(transitions, state, actorCtx, event);
2526
+ if (nextEvent.type !== init) {
2527
+ const transitions = selectTransitions(nextEvent, nextState);
2528
+ nextState = microstep(transitions, state, actorCtx, nextEvent);
2560
2529
  states.push(nextState);
2561
2530
  }
2562
2531
  while (!nextState.done) {
2563
- let enabledTransitions = selectEventlessTransitions(nextState);
2564
- if (enabledTransitions.length === 0) {
2565
- // TODO: this is a bit of a hack, we need to review this
2566
- // this matches the behavior from v4 for eventless transitions
2567
- // where for `hasAlwaysTransitions` we were always trying to resolve with a NULL event
2568
- // and if a transition was not selected the `state.transitions` stayed empty
2569
- // without this we get into an infinite loop in the dieHard test in `@xstate/test` for the `simplePathsTo`
2570
- if (nextState.configuration.some(state => state.always)) {
2571
- nextState.transitions = [];
2572
- }
2532
+ let enabledTransitions = selectEventlessTransitions(nextState, nextEvent);
2533
+ if (!enabledTransitions.length) {
2573
2534
  if (!nextState._internalQueue.length) {
2574
2535
  break;
2575
2536
  } else {
2576
- const currentActions = nextState.actions;
2577
- const nextEvent = nextState._internalQueue[0];
2537
+ nextEvent = nextState._internalQueue[0];
2578
2538
  const transitions = selectTransitions(nextEvent, nextState);
2579
2539
  nextState = microstep(transitions, nextState, actorCtx, nextEvent);
2580
2540
  nextState._internalQueue.shift();
2581
- nextState.actions.unshift(...currentActions);
2582
2541
  states.push(nextState);
2583
2542
  }
2584
- }
2585
- if (enabledTransitions.length) {
2586
- const currentActions = nextState.actions;
2587
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextState.event);
2588
- nextState.actions.unshift(...currentActions);
2543
+ } else {
2544
+ nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent);
2589
2545
  states.push(nextState);
2590
2546
  }
2591
2547
  }
2592
2548
  if (nextState.done) {
2593
2549
  // Perform the stop step to ensure that child actors are stopped
2594
- stopStep(nextState.event, nextState, actorCtx);
2550
+ stopStep(nextEvent, nextState, actorCtx);
2595
2551
  }
2596
2552
  return {
2597
2553
  state: nextState,
@@ -2606,15 +2562,12 @@ function stopStep(event, nextState, actorCtx) {
2606
2562
  for (const child of Object.values(nextState.children)) {
2607
2563
  actions.push(stop(child));
2608
2564
  }
2609
- const {
2610
- nextState: stoppedState
2611
- } = resolveActionsAndContext(actions, event, nextState, actorCtx);
2612
- return stoppedState;
2565
+ return resolveActionsAndContext(actions, event, nextState, actorCtx);
2613
2566
  }
2614
2567
  function selectTransitions(event, nextState) {
2615
2568
  return nextState.machine.getTransitionData(nextState, event);
2616
2569
  }
2617
- function selectEventlessTransitions(nextState) {
2570
+ function selectEventlessTransitions(nextState, event) {
2618
2571
  const enabledTransitionSet = new Set();
2619
2572
  const atomicStates = nextState.configuration.filter(isAtomicStateNode);
2620
2573
  for (const stateNode of atomicStates) {
@@ -2623,7 +2576,7 @@ function selectEventlessTransitions(nextState) {
2623
2576
  continue;
2624
2577
  }
2625
2578
  for (const transition of s.always) {
2626
- if (transition.guard === undefined || evaluateGuard(transition.guard, nextState.context, nextState.event, nextState)) {
2579
+ if (transition.guard === undefined || evaluateGuard(transition.guard, nextState.context, event, nextState)) {
2627
2580
  enabledTransitionSet.add(transition);
2628
2581
  break loop;
2629
2582
  }
@@ -2691,10 +2644,6 @@ class State {
2691
2644
  * The enabled state nodes representative of the state value.
2692
2645
  */
2693
2646
 
2694
- /**
2695
- * The transition definitions that resulted in this state.
2696
- */
2697
-
2698
2647
  /**
2699
2648
  * An object mapping actor names to spawned/invoked actors.
2700
2649
  */
@@ -2710,8 +2659,6 @@ class State {
2710
2659
  return new State({
2711
2660
  value: stateValue.value,
2712
2661
  context,
2713
- event: stateValue.event,
2714
- actions: [],
2715
2662
  meta: {},
2716
2663
  configuration: [],
2717
2664
  // TODO: fix,
@@ -2721,17 +2668,12 @@ class State {
2721
2668
  }
2722
2669
  return stateValue;
2723
2670
  }
2724
- const event = createInitEvent({}); // TODO: fix
2725
-
2726
2671
  const configuration = getConfiguration(getStateNodes(machine.root, stateValue));
2727
2672
  return new State({
2728
2673
  value: stateValue,
2729
2674
  context,
2730
- event,
2731
- actions: [],
2732
2675
  meta: undefined,
2733
2676
  configuration: Array.from(configuration),
2734
- transitions: [],
2735
2677
  children: {}
2736
2678
  }, machine);
2737
2679
  }
@@ -2749,23 +2691,17 @@ class State {
2749
2691
  this.output = void 0;
2750
2692
  this.context = void 0;
2751
2693
  this.historyValue = {};
2752
- this.actions = [];
2753
- this.event = void 0;
2754
2694
  this._internalQueue = void 0;
2755
2695
  this._initial = false;
2756
2696
  this.changed = void 0;
2757
2697
  this.configuration = void 0;
2758
- this.transitions = void 0;
2759
2698
  this.children = void 0;
2760
2699
  this.context = config.context;
2761
2700
  this._internalQueue = config._internalQueue ?? [];
2762
- this.event = config.event;
2763
2701
  this.historyValue = config.historyValue || {};
2764
- this.actions = config.actions ?? [];
2765
2702
  this.matches = this.matches.bind(this);
2766
2703
  this.toStrings = this.toStrings.bind(this);
2767
2704
  this.configuration = config.configuration ?? Array.from(getConfiguration(getStateNodes(machine.root, config.value)));
2768
- this.transitions = config.transitions;
2769
2705
  this.children = config.children;
2770
2706
  this.value = getStateValue(machine.root, this.configuration);
2771
2707
  this.tags = new Set(flatten(this.configuration.map(sn => sn.tags)));
@@ -2788,7 +2724,6 @@ class State {
2788
2724
  toJSON() {
2789
2725
  const {
2790
2726
  configuration,
2791
- transitions,
2792
2727
  tags,
2793
2728
  machine,
2794
2729
  ...jsonValues
@@ -2860,7 +2795,6 @@ function cloneState(state, config = {}) {
2860
2795
  function getPersistedState(state) {
2861
2796
  const {
2862
2797
  configuration,
2863
- transitions,
2864
2798
  tags,
2865
2799
  machine,
2866
2800
  children,
@@ -2879,89 +2813,105 @@ function getPersistedState(state) {
2879
2813
  };
2880
2814
  }
2881
2815
 
2882
- function invoke(invokeDef) {
2816
+ /**
2817
+ * Stops an actor.
2818
+ *
2819
+ * @param actorRef The actor to stop.
2820
+ */
2821
+
2822
+ function stop(actorRef) {
2823
+ const actor = actorRef;
2883
2824
  return createDynamicAction({
2884
- type: invoke$1,
2885
- params: invokeDef
2825
+ type: stop$1,
2826
+ params: {
2827
+ actor
2828
+ }
2886
2829
  }, (event, {
2887
- state,
2888
- actorContext
2830
+ state
2889
2831
  }) => {
2890
- const type = invoke$1;
2891
- const {
2892
- id,
2893
- src
2894
- } = invokeDef;
2895
- let resolvedInvokeAction;
2896
- if (isActorRef(src)) {
2897
- resolvedInvokeAction = {
2898
- type,
2899
- params: {
2900
- ...invokeDef,
2901
- ref: src
2902
- }
2832
+ const actorRefOrString = isFunction(actor) ? actor({
2833
+ context: state.context,
2834
+ event
2835
+ }) : actor;
2836
+ const actorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
2837
+ let children = state.children;
2838
+ if (actorRef) {
2839
+ children = {
2840
+ ...children
2903
2841
  };
2904
- } else {
2905
- const referenced = resolveReferencedActor(state.machine.options.actors[src]);
2906
- if (!referenced) {
2907
- resolvedInvokeAction = {
2908
- type,
2909
- params: invokeDef
2910
- };
2911
- } else {
2912
- const input = 'input' in invokeDef ? invokeDef.input : referenced.input;
2913
- const ref = interpret(referenced.src, {
2914
- id,
2915
- src,
2916
- parent: actorContext?.self,
2917
- systemId: invokeDef.systemId,
2918
- input: typeof input === 'function' ? input({
2919
- context: state.context,
2920
- event,
2921
- self: actorContext?.self
2922
- }) : input
2923
- });
2924
- resolvedInvokeAction = {
2925
- type,
2926
- params: {
2927
- ...invokeDef,
2928
- ref
2929
- }
2930
- };
2931
- }
2842
+ delete children[actorRef.id];
2932
2843
  }
2933
- const actorRef = resolvedInvokeAction.params.ref;
2934
- const invokedState = cloneState(state, {
2935
- children: {
2936
- ...state.children,
2937
- [id]: actorRef
2938
- }
2939
- });
2940
- resolvedInvokeAction.execute = actorCtx => {
2941
- const parent = actorCtx.self;
2942
- const {
2943
- id,
2944
- ref
2945
- } = resolvedInvokeAction.params;
2946
- if (!ref) {
2947
- {
2948
- console.warn(`Actor type '${resolvedInvokeAction.params.src}' not found in machine '${actorCtx.id}'.`);
2949
- }
2950
- return;
2951
- }
2952
- actorCtx.defer(() => {
2953
- if (actorRef.status === ActorStatus.Stopped) {
2844
+ return [cloneState(state, {
2845
+ children
2846
+ }), {
2847
+ type: 'xstate.stop',
2848
+ params: {
2849
+ actor: actorRef
2850
+ },
2851
+ execute: actorCtx => {
2852
+ if (!actorRef) {
2954
2853
  return;
2955
2854
  }
2956
- try {
2957
- actorRef.start?.();
2958
- } catch (err) {
2959
- parent.send(error(id, err));
2855
+ if (actorRef.status !== ActorStatus.Running) {
2856
+ actorCtx.stopChild(actorRef);
2960
2857
  return;
2961
2858
  }
2962
- });
2963
- };
2964
- return [invokedState, resolvedInvokeAction];
2859
+ actorCtx.defer(() => {
2860
+ actorCtx.stopChild(actorRef);
2861
+ });
2862
+ }
2863
+ }];
2864
+ });
2865
+ }
2866
+
2867
+ const defaultLogExpr = ({
2868
+ context,
2869
+ event
2870
+ }) => ({
2871
+ context,
2872
+ event
2873
+ });
2874
+
2875
+ /**
2876
+ *
2877
+ * @param expr The expression function to evaluate which will be logged.
2878
+ * Takes in 2 arguments:
2879
+ * - `ctx` - the current state context
2880
+ * - `event` - the event that caused this action to be executed.
2881
+ * @param label The label to give to the logged expression.
2882
+ */
2883
+
2884
+ function log(expr = defaultLogExpr, label) {
2885
+ return createDynamicAction({
2886
+ type: log$1,
2887
+ params: {
2888
+ label,
2889
+ expr
2890
+ }
2891
+ }, (event, {
2892
+ state,
2893
+ actorContext
2894
+ }) => {
2895
+ const resolvedValue = typeof expr === 'function' ? expr({
2896
+ context: state.context,
2897
+ event,
2898
+ self: actorContext?.self ?? {},
2899
+ system: actorContext?.system
2900
+ }) : expr;
2901
+ return [state, {
2902
+ type: 'xstate.log',
2903
+ params: {
2904
+ label,
2905
+ value: resolvedValue
2906
+ },
2907
+ execute: actorCtx => {
2908
+ if (label) {
2909
+ actorCtx.logger?.(label, resolvedValue);
2910
+ } else {
2911
+ actorCtx.logger?.(resolvedValue);
2912
+ }
2913
+ }
2914
+ }];
2965
2915
  });
2966
2916
  }
2967
2917
 
@@ -2999,7 +2949,7 @@ function createSpawner(self, machine, context, event, mutCapturedActions) {
2999
2949
  return actorRef; // TODO: fix types
3000
2950
  }
3001
2951
 
3002
- throw new Error(`Behavior '${src}' not implemented in machine '${machine.id}'`);
2952
+ throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
3003
2953
  } else {
3004
2954
  // TODO: this should also receive `src`
3005
2955
  // TODO: instead of anonymous, it should be a unique stable ID
@@ -3324,4 +3274,4 @@ function createInitEvent(input) {
3324
3274
  };
3325
3275
  }
3326
3276
 
3327
- export { toObserver as $, createInitEvent as A, resolveActionsAndContext as B, microstep as C, error as D, isStateId as E, getStateNodeByPath as F, getPersistedState as G, resolveReferencedActor as H, interpret as I, initEvent as J, matchesState as K, sendTo as L, sendParent as M, NULL_EVENT as N, forwardTo as O, Interpreter as P, ActorStatus as Q, doneInvoke as R, STATE_DELIMITER as S, assign as T, cancel as U, choose as V, log as W, pure as X, raise as Y, stop as Z, pathToStateValue as _, toArray as a, fromPromise as a0, fromObservable as a1, fromCallback as a2, fromEventObservable as a3, fromTransition as a4, stateIn as a5, not as a6, and as a7, or as a8, ActionTypes as a9, SpecialTargets as aa, startSignalType as ab, stopSignalType as ac, startSignal as ad, stopSignal as ae, isSignal as af, isActorRef as ag, toActorRef as ah, createEmptyActor as ai, toGuardDefinition as aj, actionTypes as ak, resolveActionObject as al, toActionObject as am, after as an, done as ao, send as ap, escalate as aq, toTransitionConfigArray as b, formatTransition as c, memo as d, evaluateGuard as e, formatTransitions as f, flatten as g, createInvokeId as h, isString as i, invoke$1 as j, getDelayedTransitions as k, formatInitialTransition as l, mapValues as m, getCandidates as n, toInvokeConfig as o, createSpawner as p, getConfiguration as q, getStateNodes as r, resolveStateValue as s, toActionObjects as t, isInFinalState as u, State as v, isErrorEvent as w, macrostep as x, transitionNode as y, getInitialConfiguration as z };
3277
+ export { toObserver as $, resolveActionsAndContext as A, microstep as B, error as C, isStateId as D, getStateNodeByPath as E, getPersistedState as F, resolveReferencedActor as G, interpret as H, createInitEvent as I, initEvent as J, matchesState as K, sendTo as L, sendParent as M, NULL_EVENT as N, forwardTo as O, Interpreter as P, ActorStatus as Q, doneInvoke as R, STATE_DELIMITER as S, assign as T, cancel as U, choose as V, log as W, pure as X, raise as Y, stop as Z, pathToStateValue as _, toArray as a, fromPromise as a0, fromObservable as a1, fromCallback as a2, fromEventObservable as a3, fromTransition as a4, stateIn as a5, not as a6, and as a7, or as a8, ActionTypes as a9, SpecialTargets as aa, startSignalType as ab, stopSignalType as ac, startSignal as ad, stopSignal as ae, isSignal as af, isActorRef as ag, toActorRef as ah, createEmptyActor as ai, toGuardDefinition as aj, actionTypes as ak, resolveActionObject as al, toActionObject as am, after as an, done as ao, send as ap, escalate as aq, toTransitionConfigArray as b, formatTransition as c, memo as d, evaluateGuard as e, formatTransitions as f, flatten as g, createInvokeId as h, isString as i, invoke$1 as j, getDelayedTransitions as k, formatInitialTransition as l, mapValues as m, getCandidates as n, toInvokeConfig as o, createSpawner as p, getConfiguration as q, getStateNodes as r, resolveStateValue as s, toActionObjects as t, isInFinalState as u, State as v, isErrorEvent as w, macrostep as x, transitionNode as y, getInitialConfiguration as z };