xstate 5.0.0-beta.36 → 5.0.0-beta.37

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 (41) hide show
  1. package/actions/dist/xstate-actions.cjs.js +3 -3
  2. package/actions/dist/xstate-actions.development.cjs.js +3 -3
  3. package/actions/dist/xstate-actions.development.esm.js +3 -3
  4. package/actions/dist/xstate-actions.esm.js +3 -3
  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/declarations/src/typegenTypes.d.ts +2 -0
  14. package/dist/declarations/src/types.d.ts +1 -1
  15. package/dist/declarations/src/utils.d.ts +6 -6
  16. package/dist/declarations/src/waitFor.d.ts +1 -1
  17. package/dist/{interpreter-5c4e6634.development.esm.js → interpreter-1c52b23c.development.esm.js} +13 -23
  18. package/dist/{interpreter-de5217bc.esm.js → interpreter-8def682e.esm.js} +13 -23
  19. package/dist/{interpreter-69605bf0.cjs.js → interpreter-97aff8d2.cjs.js} +13 -23
  20. package/dist/{interpreter-d3567419.development.cjs.js → interpreter-e58ca48d.development.cjs.js} +13 -23
  21. package/dist/{raise-106ea558.development.cjs.js → raise-1fd59c65.development.cjs.js} +71 -40
  22. package/dist/{raise-ffe1014a.esm.js → raise-21c417c1.esm.js} +71 -40
  23. package/dist/{raise-c51b81a3.cjs.js → raise-800296d7.cjs.js} +71 -40
  24. package/dist/{raise-5b7ad3b7.development.esm.js → raise-e342a840.development.esm.js} +71 -40
  25. package/dist/{send-778692de.cjs.js → send-4cc29786.cjs.js} +6 -3
  26. package/dist/{send-e93554d6.development.esm.js → send-83ccc98b.development.esm.js} +6 -3
  27. package/dist/{send-0a7aa74e.esm.js → send-92854675.esm.js} +6 -3
  28. package/dist/{send-25e70bd4.development.cjs.js → send-b309ef4e.development.cjs.js} +6 -3
  29. package/dist/xstate.cjs.js +5 -13
  30. package/dist/xstate.development.cjs.js +5 -13
  31. package/dist/xstate.development.esm.js +8 -16
  32. package/dist/xstate.esm.js +8 -16
  33. package/dist/xstate.umd.min.js +1 -1
  34. package/dist/xstate.umd.min.js.map +1 -1
  35. package/guards/dist/xstate-guards.cjs.js +2 -2
  36. package/guards/dist/xstate-guards.development.cjs.js +2 -2
  37. package/guards/dist/xstate-guards.development.esm.js +2 -2
  38. package/guards/dist/xstate-guards.esm.js +2 -2
  39. package/guards/dist/xstate-guards.umd.min.js +1 -1
  40. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  41. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var interpreter = require('./interpreter-69605bf0.cjs.js');
3
+ var interpreter = require('./interpreter-97aff8d2.cjs.js');
4
4
 
5
5
  const cache = new WeakMap();
6
6
  function memo(object, key, fn) {
@@ -49,14 +49,17 @@ function resolveInvoke(actorContext, state, actionArgs, {
49
49
  input,
50
50
  syncSnapshot
51
51
  }) {
52
- const referenced = interpreter.resolveReferencedActor(state.machine.implementations.actors[src]);
52
+ const referenced = typeof src === 'string' ? interpreter.resolveReferencedActor(state.machine, src) : {
53
+ src,
54
+ input: undefined
55
+ };
53
56
  let actorRef;
54
57
  if (referenced) {
55
58
  // TODO: inline `input: undefined` should win over the referenced one
56
59
  const configuredInput = input || referenced.input;
57
60
  actorRef = interpreter.createActor(referenced.src, {
58
61
  id,
59
- src,
62
+ src: typeof src === 'string' ? src : undefined,
60
63
  parent: actorContext?.self,
61
64
  systemId,
62
65
  input: typeof configuredInput === 'function' ? configuredInput({
@@ -153,11 +156,16 @@ function executeStop(actorContext, actorRef) {
153
156
  if (!actorRef) {
154
157
  return;
155
158
  }
159
+ // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
160
+ // this can happen, for example, when the invoking state is being exited immediately by an always transition
156
161
  if (actorRef.status !== interpreter.ActorStatus.Running) {
157
162
  actorContext.stopChild(actorRef);
158
163
  return;
159
164
  }
160
- // TODO: recheck why this one has to be deferred
165
+ // stopping a child enqueues a stop event in the child actor's mailbox
166
+ // we need for all of the already enqueued events to be processed before we stop the child
167
+ // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
168
+ // and we don't want to ignore those events
161
169
  actorContext.defer(() => {
162
170
  actorContext.stopChild(actorRef);
163
171
  });
@@ -181,7 +189,8 @@ function checkStateIn(state, _, {
181
189
  stateValue
182
190
  }) {
183
191
  if (typeof stateValue === 'string' && isStateId(stateValue)) {
184
- return state.configuration.some(sn => sn.id === stateValue.slice(1));
192
+ const target = state.machine.getStateNodeById(stateValue);
193
+ return state.configuration.some(sn => sn === target);
185
194
  }
186
195
  return state.matches(stateValue);
187
196
  }
@@ -285,6 +294,9 @@ function getChildren(stateNode) {
285
294
  }
286
295
  function getProperAncestors(stateNode, toStateNode) {
287
296
  const ancestors = [];
297
+ if (toStateNode === stateNode) {
298
+ return ancestors;
299
+ }
288
300
 
289
301
  // add all ancestors
290
302
  let m = stateNode.parent;
@@ -561,12 +573,14 @@ function resolveTarget(stateNode, targets) {
561
573
  }
562
574
  });
563
575
  }
564
- function resolveHistoryTarget(stateNode) {
576
+ function resolveHistoryDefaultTransition(stateNode) {
565
577
  const normalizedTarget = interpreter.normalizeTarget(stateNode.config.target);
566
578
  if (!normalizedTarget) {
567
- return stateNode.parent.initial.target;
579
+ return stateNode.parent.initial;
568
580
  }
569
- return normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t);
581
+ return {
582
+ target: normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t)
583
+ };
570
584
  }
571
585
  function isHistoryNode(stateNode) {
572
586
  return stateNode.type === 'history';
@@ -793,9 +807,7 @@ function getEffectiveTargetStates(transition, historyValue) {
793
807
  targets.add(node);
794
808
  }
795
809
  } else {
796
- for (const node of getEffectiveTargetStates({
797
- target: resolveHistoryTarget(targetNode)
798
- }, historyValue)) {
810
+ for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) {
799
811
  targets.add(node);
800
812
  }
801
813
  }
@@ -808,9 +820,9 @@ function getEffectiveTargetStates(transition, historyValue) {
808
820
  function getTransitionDomain(transition, historyValue) {
809
821
  const targetStates = getEffectiveTargetStates(transition, historyValue);
810
822
  if (!targetStates) {
811
- return null;
823
+ return;
812
824
  }
813
- if (!transition.reenter && transition.source.type !== 'parallel' && targetStates.every(targetStateNode => isDescendant(targetStateNode, transition.source))) {
825
+ if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
814
826
  return transition.source;
815
827
  }
816
828
  const lcca = findLCCA(targetStates.concat(transition.source));
@@ -821,6 +833,9 @@ function computeExitSet(transitions, configuration, historyValue) {
821
833
  for (const t of transitions) {
822
834
  if (t.target?.length) {
823
835
  const domain = getTransitionDomain(t, historyValue);
836
+ if (t.reenter && t.source === domain) {
837
+ statesToExit.add(domain);
838
+ }
824
839
  for (const stateNode of configuration) {
825
840
  if (isDescendant(stateNode, domain)) {
826
841
  statesToExit.add(stateNode);
@@ -897,6 +912,9 @@ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode)
897
912
  function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
898
913
  let nextState = currentState;
899
914
  const statesToEnter = new Set();
915
+ // those are states that were directly targeted or indirectly targeted by the explicit target
916
+ // in other words, those are states for which initial actions should be executed
917
+ // when we target `#deep_child` initial actions of its ancestors shouldn't be executed
900
918
  const statesForDefaultEntry = new Set();
901
919
  computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
902
920
 
@@ -921,20 +939,16 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
921
939
  nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
922
940
  if (stateNodeToEnter.type === 'final') {
923
941
  const parent = stateNodeToEnter.parent;
924
- if (completedNodes.has(parent)) {
925
- continue;
926
- }
927
- completedNodes.add(parent);
928
- let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
929
- let ancestorMarker = parent?.parent;
930
- if (ancestorMarker) {
942
+ let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
943
+ let rootCompletionNode = ancestorMarker || stateNodeToEnter;
944
+ if (parent?.type === 'compound') {
931
945
  internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
932
- while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
933
- completedNodes.add(ancestorMarker);
934
- internalQueue.push(interpreter.createDoneStateEvent(ancestorMarker.id));
935
- rootCompletionNode = ancestorMarker;
936
- ancestorMarker = ancestorMarker.parent;
937
- }
946
+ }
947
+ while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
948
+ completedNodes.add(ancestorMarker);
949
+ internalQueue.push(interpreter.createDoneStateEvent(ancestorMarker.id));
950
+ rootCompletionNode = ancestorMarker;
951
+ ancestorMarker = ancestorMarker.parent;
938
952
  }
939
953
  if (ancestorMarker) {
940
954
  continue;
@@ -949,13 +963,24 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
949
963
  }
950
964
  function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
951
965
  for (const t of transitions) {
966
+ const domain = getTransitionDomain(t, historyValue);
952
967
  for (const s of t.target || []) {
968
+ if (!isHistoryNode(s) && (
969
+ // if the target is different than the source then it will *definitely* be entered
970
+ t.source !== s ||
971
+ // we know that the domain can't lie within the source
972
+ // if it's different than the source then it's outside of it and it means that the target has to be entered as well
973
+ t.source !== domain ||
974
+ // reentering transitions always enter the target, even if it's the source itself
975
+ t.reenter)) {
976
+ statesToEnter.add(s);
977
+ statesForDefaultEntry.add(s);
978
+ }
953
979
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
954
980
  }
955
- const ancestor = getTransitionDomain(t, historyValue);
956
981
  const targetStates = getEffectiveTargetStates(t, historyValue);
957
982
  for (const s of targetStates) {
958
- addAncestorStatesToEnter(s, ancestor, statesToEnter, historyValue, statesForDefaultEntry);
983
+ addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
959
984
  }
960
985
  }
961
986
  }
@@ -964,37 +989,42 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
964
989
  if (historyValue[stateNode.id]) {
965
990
  const historyStateNodes = historyValue[stateNode.id];
966
991
  for (const s of historyStateNodes) {
992
+ statesToEnter.add(s);
967
993
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
968
994
  }
969
995
  for (const s of historyStateNodes) {
970
996
  addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
971
- for (const stateForDefaultEntry of statesForDefaultEntry) {
972
- statesForDefaultEntry.add(stateForDefaultEntry);
973
- }
974
997
  }
975
998
  } else {
976
- const targets = resolveHistoryTarget(stateNode);
977
- for (const s of targets) {
999
+ const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
1000
+ for (const s of historyDefaultTransition.target) {
1001
+ statesToEnter.add(s);
1002
+ if (historyDefaultTransition === stateNode.parent?.initial) {
1003
+ statesForDefaultEntry.add(stateNode.parent);
1004
+ }
978
1005
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
979
1006
  }
980
- for (const s of targets) {
1007
+ for (const s of historyDefaultTransition.target) {
981
1008
  addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
982
- for (const stateForDefaultEntry of statesForDefaultEntry) {
983
- statesForDefaultEntry.add(stateForDefaultEntry);
984
- }
985
1009
  }
986
1010
  }
987
1011
  } else {
988
- statesToEnter.add(stateNode);
989
1012
  if (stateNode.type === 'compound') {
990
- statesForDefaultEntry.add(stateNode);
991
1013
  const [initialState] = stateNode.initial.target;
1014
+ if (!isHistoryNode(initialState)) {
1015
+ statesToEnter.add(initialState);
1016
+ statesForDefaultEntry.add(initialState);
1017
+ }
992
1018
  addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
993
1019
  addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
994
1020
  } else {
995
1021
  if (stateNode.type === 'parallel') {
996
1022
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
997
1023
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1024
+ if (!isHistoryNode(child)) {
1025
+ statesToEnter.add(child);
1026
+ statesForDefaultEntry.add(child);
1027
+ }
998
1028
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
999
1029
  }
1000
1030
  }
@@ -1009,6 +1039,7 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1009
1039
  if (anc.type === 'parallel') {
1010
1040
  for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
1011
1041
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1042
+ statesToEnter.add(child);
1012
1043
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
1013
1044
  }
1014
1045
  }
@@ -1176,7 +1207,7 @@ function selectEventlessTransitions(nextState, event) {
1176
1207
  const enabledTransitionSet = new Set();
1177
1208
  const atomicStates = nextState.configuration.filter(isAtomicStateNode);
1178
1209
  for (const stateNode of atomicStates) {
1179
- loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, null))) {
1210
+ loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, undefined))) {
1180
1211
  if (!s.always) {
1181
1212
  continue;
1182
1213
  }
@@ -1,4 +1,4 @@
1
- import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, W as WILDCARD, X as XSTATE_STOP, u as XSTATE_INIT, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-5c4e6634.development.esm.js';
1
+ import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, W as WILDCARD, X as XSTATE_STOP, u as XSTATE_INIT, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-1c52b23c.development.esm.js';
2
2
 
3
3
  const cache = new WeakMap();
4
4
  function memo(object, key, fn) {
@@ -50,14 +50,17 @@ function resolveInvoke(actorContext, state, actionArgs, {
50
50
  input,
51
51
  syncSnapshot
52
52
  }) {
53
- const referenced = resolveReferencedActor(state.machine.implementations.actors[src]);
53
+ const referenced = typeof src === 'string' ? resolveReferencedActor(state.machine, src) : {
54
+ src,
55
+ input: undefined
56
+ };
54
57
  let actorRef;
55
58
  if (referenced) {
56
59
  // TODO: inline `input: undefined` should win over the referenced one
57
60
  const configuredInput = input || referenced.input;
58
61
  actorRef = createActor(referenced.src, {
59
62
  id,
60
- src,
63
+ src: typeof src === 'string' ? src : undefined,
61
64
  parent: actorContext?.self,
62
65
  systemId,
63
66
  input: typeof configuredInput === 'function' ? configuredInput({
@@ -160,11 +163,16 @@ function executeStop(actorContext, actorRef) {
160
163
  if (!actorRef) {
161
164
  return;
162
165
  }
166
+ // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
167
+ // this can happen, for example, when the invoking state is being exited immediately by an always transition
163
168
  if (actorRef.status !== ActorStatus.Running) {
164
169
  actorContext.stopChild(actorRef);
165
170
  return;
166
171
  }
167
- // TODO: recheck why this one has to be deferred
172
+ // stopping a child enqueues a stop event in the child actor's mailbox
173
+ // we need for all of the already enqueued events to be processed before we stop the child
174
+ // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
175
+ // and we don't want to ignore those events
168
176
  actorContext.defer(() => {
169
177
  actorContext.stopChild(actorRef);
170
178
  });
@@ -191,7 +199,8 @@ function checkStateIn(state, _, {
191
199
  stateValue
192
200
  }) {
193
201
  if (typeof stateValue === 'string' && isStateId(stateValue)) {
194
- return state.configuration.some(sn => sn.id === stateValue.slice(1));
202
+ const target = state.machine.getStateNodeById(stateValue);
203
+ return state.configuration.some(sn => sn === target);
195
204
  }
196
205
  return state.matches(stateValue);
197
206
  }
@@ -303,6 +312,9 @@ function getChildren(stateNode) {
303
312
  }
304
313
  function getProperAncestors(stateNode, toStateNode) {
305
314
  const ancestors = [];
315
+ if (toStateNode === stateNode) {
316
+ return ancestors;
317
+ }
306
318
 
307
319
  // add all ancestors
308
320
  let m = stateNode.parent;
@@ -590,12 +602,14 @@ function resolveTarget(stateNode, targets) {
590
602
  }
591
603
  });
592
604
  }
593
- function resolveHistoryTarget(stateNode) {
605
+ function resolveHistoryDefaultTransition(stateNode) {
594
606
  const normalizedTarget = normalizeTarget(stateNode.config.target);
595
607
  if (!normalizedTarget) {
596
- return stateNode.parent.initial.target;
608
+ return stateNode.parent.initial;
597
609
  }
598
- return normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t);
610
+ return {
611
+ target: normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t)
612
+ };
599
613
  }
600
614
  function isHistoryNode(stateNode) {
601
615
  return stateNode.type === 'history';
@@ -822,9 +836,7 @@ function getEffectiveTargetStates(transition, historyValue) {
822
836
  targets.add(node);
823
837
  }
824
838
  } else {
825
- for (const node of getEffectiveTargetStates({
826
- target: resolveHistoryTarget(targetNode)
827
- }, historyValue)) {
839
+ for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) {
828
840
  targets.add(node);
829
841
  }
830
842
  }
@@ -837,9 +849,9 @@ function getEffectiveTargetStates(transition, historyValue) {
837
849
  function getTransitionDomain(transition, historyValue) {
838
850
  const targetStates = getEffectiveTargetStates(transition, historyValue);
839
851
  if (!targetStates) {
840
- return null;
852
+ return;
841
853
  }
842
- if (!transition.reenter && transition.source.type !== 'parallel' && targetStates.every(targetStateNode => isDescendant(targetStateNode, transition.source))) {
854
+ if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
843
855
  return transition.source;
844
856
  }
845
857
  const lcca = findLCCA(targetStates.concat(transition.source));
@@ -850,6 +862,9 @@ function computeExitSet(transitions, configuration, historyValue) {
850
862
  for (const t of transitions) {
851
863
  if (t.target?.length) {
852
864
  const domain = getTransitionDomain(t, historyValue);
865
+ if (t.reenter && t.source === domain) {
866
+ statesToExit.add(domain);
867
+ }
853
868
  for (const stateNode of configuration) {
854
869
  if (isDescendant(stateNode, domain)) {
855
870
  statesToExit.add(stateNode);
@@ -926,6 +941,9 @@ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode)
926
941
  function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
927
942
  let nextState = currentState;
928
943
  const statesToEnter = new Set();
944
+ // those are states that were directly targeted or indirectly targeted by the explicit target
945
+ // in other words, those are states for which initial actions should be executed
946
+ // when we target `#deep_child` initial actions of its ancestors shouldn't be executed
929
947
  const statesForDefaultEntry = new Set();
930
948
  computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
931
949
 
@@ -950,20 +968,16 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
950
968
  nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
951
969
  if (stateNodeToEnter.type === 'final') {
952
970
  const parent = stateNodeToEnter.parent;
953
- if (completedNodes.has(parent)) {
954
- continue;
955
- }
956
- completedNodes.add(parent);
957
- let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
958
- let ancestorMarker = parent?.parent;
959
- if (ancestorMarker) {
971
+ let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
972
+ let rootCompletionNode = ancestorMarker || stateNodeToEnter;
973
+ if (parent?.type === 'compound') {
960
974
  internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
961
- while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
962
- completedNodes.add(ancestorMarker);
963
- internalQueue.push(createDoneStateEvent(ancestorMarker.id));
964
- rootCompletionNode = ancestorMarker;
965
- ancestorMarker = ancestorMarker.parent;
966
- }
975
+ }
976
+ while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
977
+ completedNodes.add(ancestorMarker);
978
+ internalQueue.push(createDoneStateEvent(ancestorMarker.id));
979
+ rootCompletionNode = ancestorMarker;
980
+ ancestorMarker = ancestorMarker.parent;
967
981
  }
968
982
  if (ancestorMarker) {
969
983
  continue;
@@ -978,13 +992,24 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
978
992
  }
979
993
  function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
980
994
  for (const t of transitions) {
995
+ const domain = getTransitionDomain(t, historyValue);
981
996
  for (const s of t.target || []) {
997
+ if (!isHistoryNode(s) && (
998
+ // if the target is different than the source then it will *definitely* be entered
999
+ t.source !== s ||
1000
+ // we know that the domain can't lie within the source
1001
+ // if it's different than the source then it's outside of it and it means that the target has to be entered as well
1002
+ t.source !== domain ||
1003
+ // reentering transitions always enter the target, even if it's the source itself
1004
+ t.reenter)) {
1005
+ statesToEnter.add(s);
1006
+ statesForDefaultEntry.add(s);
1007
+ }
982
1008
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
983
1009
  }
984
- const ancestor = getTransitionDomain(t, historyValue);
985
1010
  const targetStates = getEffectiveTargetStates(t, historyValue);
986
1011
  for (const s of targetStates) {
987
- addAncestorStatesToEnter(s, ancestor, statesToEnter, historyValue, statesForDefaultEntry);
1012
+ addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
988
1013
  }
989
1014
  }
990
1015
  }
@@ -993,37 +1018,42 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
993
1018
  if (historyValue[stateNode.id]) {
994
1019
  const historyStateNodes = historyValue[stateNode.id];
995
1020
  for (const s of historyStateNodes) {
1021
+ statesToEnter.add(s);
996
1022
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
997
1023
  }
998
1024
  for (const s of historyStateNodes) {
999
1025
  addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
1000
- for (const stateForDefaultEntry of statesForDefaultEntry) {
1001
- statesForDefaultEntry.add(stateForDefaultEntry);
1002
- }
1003
1026
  }
1004
1027
  } else {
1005
- const targets = resolveHistoryTarget(stateNode);
1006
- for (const s of targets) {
1028
+ const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
1029
+ for (const s of historyDefaultTransition.target) {
1030
+ statesToEnter.add(s);
1031
+ if (historyDefaultTransition === stateNode.parent?.initial) {
1032
+ statesForDefaultEntry.add(stateNode.parent);
1033
+ }
1007
1034
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1008
1035
  }
1009
- for (const s of targets) {
1036
+ for (const s of historyDefaultTransition.target) {
1010
1037
  addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1011
- for (const stateForDefaultEntry of statesForDefaultEntry) {
1012
- statesForDefaultEntry.add(stateForDefaultEntry);
1013
- }
1014
1038
  }
1015
1039
  }
1016
1040
  } else {
1017
- statesToEnter.add(stateNode);
1018
1041
  if (stateNode.type === 'compound') {
1019
- statesForDefaultEntry.add(stateNode);
1020
1042
  const [initialState] = stateNode.initial.target;
1043
+ if (!isHistoryNode(initialState)) {
1044
+ statesToEnter.add(initialState);
1045
+ statesForDefaultEntry.add(initialState);
1046
+ }
1021
1047
  addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1022
1048
  addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1023
1049
  } else {
1024
1050
  if (stateNode.type === 'parallel') {
1025
1051
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
1026
1052
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1053
+ if (!isHistoryNode(child)) {
1054
+ statesToEnter.add(child);
1055
+ statesForDefaultEntry.add(child);
1056
+ }
1027
1057
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
1028
1058
  }
1029
1059
  }
@@ -1038,6 +1068,7 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1038
1068
  if (anc.type === 'parallel') {
1039
1069
  for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
1040
1070
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1071
+ statesToEnter.add(child);
1041
1072
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
1042
1073
  }
1043
1074
  }
@@ -1208,7 +1239,7 @@ function selectEventlessTransitions(nextState, event) {
1208
1239
  const enabledTransitionSet = new Set();
1209
1240
  const atomicStates = nextState.configuration.filter(isAtomicStateNode);
1210
1241
  for (const stateNode of atomicStates) {
1211
- loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, null))) {
1242
+ loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, undefined))) {
1212
1243
  if (!s.always) {
1213
1244
  continue;
1214
1245
  }
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-c51b81a3.cjs.js');
4
- var interpreter = require('./interpreter-69605bf0.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-800296d7.cjs.js');
4
+ var interpreter = require('./interpreter-97aff8d2.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
7
7
  machine,
@@ -12,7 +12,7 @@ function createSpawner(actorContext, {
12
12
  systemId
13
13
  } = options;
14
14
  if (typeof src === 'string') {
15
- const referenced = interpreter.resolveReferencedActor(machine.implementations.actors[src]);
15
+ const referenced = interpreter.resolveReferencedActor(machine, src);
16
16
  if (!referenced) {
17
17
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
18
18
  }
@@ -310,6 +310,9 @@ function executeSendTo(actorContext, params) {
310
310
  actorContext.self.delaySend(params);
311
311
  return;
312
312
  }
313
+
314
+ // this forms an outgoing events queue
315
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
313
316
  actorContext.defer(() => {
314
317
  const {
315
318
  to,
@@ -1,5 +1,5 @@
1
- import { j as cloneState, e as evaluateGuard } from './raise-5b7ad3b7.development.esm.js';
2
- import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, x as XSTATE_ERROR } from './interpreter-5c4e6634.development.esm.js';
1
+ import { j as cloneState, e as evaluateGuard } from './raise-e342a840.development.esm.js';
2
+ import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, x as XSTATE_ERROR } from './interpreter-1c52b23c.development.esm.js';
3
3
 
4
4
  function createSpawner(actorContext, {
5
5
  machine,
@@ -10,7 +10,7 @@ function createSpawner(actorContext, {
10
10
  systemId
11
11
  } = options;
12
12
  if (typeof src === 'string') {
13
- const referenced = resolveReferencedActor(machine.implementations.actors[src]);
13
+ const referenced = resolveReferencedActor(machine, src);
14
14
  if (!referenced) {
15
15
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
16
16
  }
@@ -320,6 +320,9 @@ function executeSendTo(actorContext, params) {
320
320
  actorContext.self.delaySend(params);
321
321
  return;
322
322
  }
323
+
324
+ // this forms an outgoing events queue
325
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
323
326
  actorContext.defer(() => {
324
327
  const {
325
328
  to,
@@ -1,5 +1,5 @@
1
- import { j as cloneState, e as evaluateGuard } from './raise-ffe1014a.esm.js';
2
- import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, x as XSTATE_ERROR } from './interpreter-de5217bc.esm.js';
1
+ import { j as cloneState, e as evaluateGuard } from './raise-21c417c1.esm.js';
2
+ import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, x as XSTATE_ERROR } from './interpreter-8def682e.esm.js';
3
3
 
4
4
  function createSpawner(actorContext, {
5
5
  machine,
@@ -10,7 +10,7 @@ function createSpawner(actorContext, {
10
10
  systemId
11
11
  } = options;
12
12
  if (typeof src === 'string') {
13
- const referenced = resolveReferencedActor(machine.implementations.actors[src]);
13
+ const referenced = resolveReferencedActor(machine, src);
14
14
  if (!referenced) {
15
15
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
16
16
  }
@@ -308,6 +308,9 @@ function executeSendTo(actorContext, params) {
308
308
  actorContext.self.delaySend(params);
309
309
  return;
310
310
  }
311
+
312
+ // this forms an outgoing events queue
313
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
311
314
  actorContext.defer(() => {
312
315
  const {
313
316
  to,
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-106ea558.development.cjs.js');
4
- var interpreter = require('./interpreter-d3567419.development.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-1fd59c65.development.cjs.js');
4
+ var interpreter = require('./interpreter-e58ca48d.development.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
7
7
  machine,
@@ -12,7 +12,7 @@ function createSpawner(actorContext, {
12
12
  systemId
13
13
  } = options;
14
14
  if (typeof src === 'string') {
15
- const referenced = interpreter.resolveReferencedActor(machine.implementations.actors[src]);
15
+ const referenced = interpreter.resolveReferencedActor(machine, src);
16
16
  if (!referenced) {
17
17
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
18
18
  }
@@ -322,6 +322,9 @@ function executeSendTo(actorContext, params) {
322
322
  actorContext.self.delaySend(params);
323
323
  return;
324
324
  }
325
+
326
+ // this forms an outgoing events queue
327
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
325
328
  actorContext.defer(() => {
326
329
  const {
327
330
  to,
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var actors_dist_xstateActors = require('../actors/dist/xstate-actors.cjs.js');
6
- var interpreter = require('./interpreter-69605bf0.cjs.js');
7
- var guards_dist_xstateGuards = require('./raise-c51b81a3.cjs.js');
8
- var send = require('./send-778692de.cjs.js');
6
+ var interpreter = require('./interpreter-97aff8d2.cjs.js');
7
+ var guards_dist_xstateGuards = require('./raise-800296d7.cjs.js');
8
+ var send = require('./send-4cc29786.cjs.js');
9
9
  require('../dev/dist/xstate-dev.cjs.js');
10
10
 
11
11
  class SimulatedClock {
@@ -255,15 +255,7 @@ class StateNode {
255
255
  systemId
256
256
  } = invokeConfig;
257
257
  const resolvedId = invokeConfig.id || interpreter.createInvokeId(this.id, i);
258
- // TODO: resolving should not happen here
259
- const resolvedSrc = typeof src === 'string' ? src : !('type' in src) ? resolvedId : src;
260
- if (!this.machine.implementations.actors[resolvedId] && typeof src !== 'string' && !('type' in src)) {
261
- this.machine.implementations.actors = {
262
- ...this.machine.implementations.actors,
263
- // TODO: this should accept `src` as-is
264
- [resolvedId]: src
265
- };
266
- }
258
+ const resolvedSrc = typeof src === 'string' ? src : `xstate#${interpreter.createInvokeId(this.id, i)}`;
267
259
  return {
268
260
  ...invokeConfig,
269
261
  src: resolvedSrc,
@@ -599,7 +591,7 @@ class StateMachine {
599
591
  const actorData = snapshot.children[actorId];
600
592
  const childState = actorData.state;
601
593
  const src = actorData.src;
602
- const logic = src ? interpreter.resolveReferencedActor(this.implementations.actors[src])?.src : undefined;
594
+ const logic = src ? interpreter.resolveReferencedActor(this, src)?.src : undefined;
603
595
  if (!logic) {
604
596
  return;
605
597
  }