xstate 5.0.0-beta.34 → 5.0.0-beta.35

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 (40) hide show
  1. package/README.md +1 -1
  2. package/actions/dist/xstate-actions.cjs.js +3 -3
  3. package/actions/dist/xstate-actions.development.cjs.js +3 -3
  4. package/actions/dist/xstate-actions.development.esm.js +3 -3
  5. package/actions/dist/xstate-actions.esm.js +3 -3
  6. package/actions/dist/xstate-actions.umd.min.js +1 -1
  7. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  8. package/actors/dist/xstate-actors.cjs.js +1 -1
  9. package/actors/dist/xstate-actors.development.cjs.js +1 -1
  10. package/actors/dist/xstate-actors.development.esm.js +1 -1
  11. package/actors/dist/xstate-actors.esm.js +1 -1
  12. package/actors/dist/xstate-actors.umd.min.js +1 -1
  13. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  14. package/dist/declarations/src/interpreter.d.ts +2 -0
  15. package/dist/declarations/src/stateUtils.d.ts +5 -4
  16. package/dist/declarations/src/types.d.ts +3 -5
  17. package/dist/{interpreter-dee56dc8.development.esm.js → interpreter-5c4e6634.development.esm.js} +59 -57
  18. package/dist/{interpreter-1301970f.cjs.js → interpreter-69605bf0.cjs.js} +59 -57
  19. package/dist/{interpreter-70ed62f2.development.cjs.js → interpreter-d3567419.development.cjs.js} +59 -57
  20. package/dist/{interpreter-83f7f2d4.esm.js → interpreter-de5217bc.esm.js} +59 -57
  21. package/dist/{raise-1dd65455.cjs.js → raise-0ff57677.cjs.js} +100 -99
  22. package/dist/{raise-38b707c0.development.cjs.js → raise-26e4d83c.development.cjs.js} +103 -99
  23. package/dist/{raise-b5cfe1bb.esm.js → raise-511399cc.esm.js} +100 -99
  24. package/dist/{raise-05f8b2a6.development.esm.js → raise-cdcdf834.development.esm.js} +103 -99
  25. package/dist/{send-fe94de2b.cjs.js → send-19ffc568.cjs.js} +4 -2
  26. package/dist/{send-9526366e.development.esm.js → send-1de74f4d.development.esm.js} +4 -2
  27. package/dist/{send-0b5eda0c.esm.js → send-211a2a94.esm.js} +4 -2
  28. package/dist/{send-3764c866.development.cjs.js → send-894c4b18.development.cjs.js} +4 -2
  29. package/dist/xstate.cjs.js +26 -7
  30. package/dist/xstate.development.cjs.js +26 -7
  31. package/dist/xstate.development.esm.js +29 -10
  32. package/dist/xstate.esm.js +29 -10
  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.map +1 -1
  40. package/package.json +1 -1
@@ -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, X as XSTATE_STOP, u as XSTATE_INIT, W as WILDCARD, v as isArray, w as createAfterEvent, x as flatten, e as matchesState } from './interpreter-83f7f2d4.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, X as XSTATE_STOP, u as XSTATE_INIT, W as WILDCARD, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-de5217bc.esm.js';
2
2
 
3
3
  const cache = new WeakMap();
4
4
  function memo(object, key, fn) {
@@ -277,20 +277,6 @@ function evaluateGuard(guard, context, event, state) {
277
277
  );
278
278
  }
279
279
 
280
- function getOutput(configuration, context, event, self) {
281
- const {
282
- machine
283
- } = configuration[0];
284
- const {
285
- root
286
- } = machine;
287
- if (!root.output) {
288
- return undefined;
289
- }
290
- const finalChildStateNode = configuration.find(stateNode => stateNode.type === 'final' && stateNode.parent === machine.root);
291
- const doneStateEvent = createDoneStateEvent(finalChildStateNode.id, finalChildStateNode.output ? resolveOutput(finalChildStateNode.output, context, event, self) : undefined);
292
- return resolveOutput(root.output, context, doneStateEvent, self);
293
- }
294
280
  const isAtomicStateNode = stateNode => stateNode.type === 'atomic' || stateNode.type === 'final';
295
281
  function getChildren(stateNode) {
296
282
  return Object.values(stateNode.states).filter(sn => sn.type !== 'history');
@@ -315,7 +301,7 @@ function getConfiguration(stateNodes) {
315
301
  for (const s of configuration) {
316
302
  // if previously active, add existing child nodes
317
303
  if (s.type === 'compound' && (!adjList.get(s) || !adjList.get(s).length)) {
318
- getInitialStateNodes(s).forEach(sn => configurationSet.add(sn));
304
+ getInitialStateNodesWithTheirAncestors(s).forEach(sn => configurationSet.add(sn));
319
305
  } else {
320
306
  if (s.type === 'parallel') {
321
307
  for (const child of getChildren(s)) {
@@ -323,7 +309,8 @@ function getConfiguration(stateNodes) {
323
309
  continue;
324
310
  }
325
311
  if (!configurationSet.has(child)) {
326
- for (const initialStateNode of getInitialStateNodes(child)) {
312
+ const initialStates = getInitialStateNodesWithTheirAncestors(child);
313
+ for (const initialStateNode of initialStates) {
327
314
  configurationSet.add(initialStateNode);
328
315
  }
329
316
  }
@@ -383,14 +370,14 @@ function getStateValue(rootNode, configuration) {
383
370
  const config = getConfiguration(configuration);
384
371
  return getValueFromAdj(rootNode, getAdjList(config));
385
372
  }
386
- function isInFinalState(configuration, stateNode = configuration[0].machine.root) {
373
+ function isInFinalState(configuration, stateNode) {
387
374
  if (stateNode.type === 'compound') {
388
- return getChildren(stateNode).some(s => s.type === 'final' && configuration.includes(s));
375
+ return getChildren(stateNode).some(s => s.type === 'final' && configuration.has(s));
389
376
  }
390
377
  if (stateNode.type === 'parallel') {
391
378
  return getChildren(stateNode).every(sn => isInFinalState(configuration, sn));
392
379
  }
393
- return false;
380
+ return stateNode.type === 'final';
394
381
  }
395
382
  const isStateId = str => str[0] === STATE_IDENTIFIER;
396
383
  function getCandidates(stateNode, receivedEventType) {
@@ -440,13 +427,7 @@ function getDelayedTransitions(stateNode) {
440
427
  stateNode.exit.push(cancel(eventType));
441
428
  return eventType;
442
429
  };
443
- const delayedTransitions = isArray(afterConfig) ? afterConfig.map((transition, i) => {
444
- const eventType = mutateEntryExit(transition.delay, i);
445
- return {
446
- ...transition,
447
- event: eventType
448
- };
449
- }) : Object.keys(afterConfig).flatMap((delay, i) => {
430
+ const delayedTransitions = Object.keys(afterConfig).flatMap((delay, i) => {
450
431
  const configTransition = afterConfig[delay];
451
432
  const resolvedTransition = typeof configTransition === 'string' ? {
452
433
  target: configTransition
@@ -529,43 +510,23 @@ function formatTransitions(stateNode) {
529
510
  return transitions;
530
511
  }
531
512
  function formatInitialTransition(stateNode, _target) {
532
- if (typeof _target === 'string' || isArray(_target)) {
533
- const targets = toArray(_target).map(t => {
534
- // Resolve state string keys (which represent children)
535
- // to their state node
536
- const descStateNode = typeof t === 'string' ? isStateId(t) ? stateNode.machine.getStateNodeById(t) : stateNode.states[t] : t;
537
- if (!descStateNode) {
538
- throw new Error(`Initial state node "${t}" not found on parent state node #${stateNode.id}`);
539
- }
540
- if (!isDescendant(descStateNode, stateNode)) {
541
- throw new Error(`Invalid initial target: state node #${descStateNode.id} is not a descendant of #${stateNode.id}`);
542
- }
543
- return descStateNode;
544
- });
545
- const resolvedTarget = resolveTarget(stateNode, targets);
546
- const transition = {
547
- source: stateNode,
548
- actions: [],
549
- eventType: null,
550
- reenter: false,
551
- target: resolvedTarget,
552
- toJSON: () => ({
553
- ...transition,
554
- source: `#${stateNode.id}`,
555
- target: resolvedTarget ? resolvedTarget.map(t => `#${t.id}`) : undefined
556
- })
557
- };
558
- return transition;
513
+ const resolvedTarget = typeof _target === 'string' ? stateNode.states[_target] : _target ? stateNode.states[_target.target] : undefined;
514
+ if (!resolvedTarget && _target) {
515
+ throw new Error(`Initial state node "${_target}" not found on parent state node #${stateNode.id}`);
559
516
  }
560
- return formatTransition(stateNode, '__INITIAL__', {
561
- target: toArray(_target.target).map(t => {
562
- if (typeof t === 'string') {
563
- return isStateId(t) ? t : `${STATE_DELIMITER}${t}`;
564
- }
565
- return t;
566
- }),
567
- actions: _target.actions
568
- });
517
+ const transition = {
518
+ source: stateNode,
519
+ actions: !_target || typeof _target === 'string' ? [] : toArray(_target.actions),
520
+ eventType: null,
521
+ reenter: false,
522
+ target: resolvedTarget ? [resolvedTarget] : [],
523
+ toJSON: () => ({
524
+ ...transition,
525
+ source: `#${stateNode.id}`,
526
+ target: resolvedTarget ? [`#${resolvedTarget.id}`] : []
527
+ })
528
+ };
529
+ return transition;
569
530
  }
570
531
  function resolveTarget(stateNode, targets) {
571
532
  if (targets === undefined) {
@@ -608,6 +569,15 @@ function resolveHistoryTarget(stateNode) {
608
569
  function isHistoryNode(stateNode) {
609
570
  return stateNode.type === 'history';
610
571
  }
572
+ function getInitialStateNodesWithTheirAncestors(stateNode) {
573
+ const states = getInitialStateNodes(stateNode);
574
+ for (const initialState of states) {
575
+ for (const ancestor of getProperAncestors(initialState, stateNode)) {
576
+ states.add(ancestor);
577
+ }
578
+ }
579
+ return states;
580
+ }
611
581
  function getInitialStateNodes(stateNode) {
612
582
  const set = new Set();
613
583
  function iter(descStateNode) {
@@ -616,12 +586,7 @@ function getInitialStateNodes(stateNode) {
616
586
  }
617
587
  set.add(descStateNode);
618
588
  if (descStateNode.type === 'compound') {
619
- for (const targetStateNode of descStateNode.initial.target) {
620
- for (const a of getProperAncestors(targetStateNode, stateNode)) {
621
- set.add(a);
622
- }
623
- iter(targetStateNode);
624
- }
589
+ iter(descStateNode.initial.target[0]);
625
590
  } else if (descStateNode.type === 'parallel') {
626
591
  for (const child of getChildren(descStateNode)) {
627
592
  iter(child);
@@ -629,7 +594,7 @@ function getInitialStateNodes(stateNode) {
629
594
  }
630
595
  }
631
596
  iter(stateNode);
632
- return [...set];
597
+ return set;
633
598
  }
634
599
  /**
635
600
  * Returns the child state node from its relative `stateKey`, or throws.
@@ -907,21 +872,15 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
907
872
  // Enter states
908
873
  nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
909
874
  const nextConfiguration = [...mutConfiguration];
910
- const done = isInFinalState(nextConfiguration);
911
- if (done) {
875
+ if (nextState.status === 'done') {
912
876
  nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit));
913
877
  }
914
878
  try {
915
- const output = done ? getOutput(nextConfiguration, nextState.context, event, actorCtx.self) : undefined;
916
879
  internalQueue.push(...nextState._internalQueue);
917
- return cloneState(currentState, {
880
+ return cloneState(nextState, {
918
881
  configuration: nextConfiguration,
919
882
  historyValue,
920
- _internalQueue: internalQueue,
921
- context: nextState.context,
922
- status: done ? 'done' : currentState.status,
923
- output,
924
- children: nextState.children
883
+ _internalQueue: internalQueue
925
884
  });
926
885
  } catch (e) {
927
886
  // TODO: Refactor this once proper error handling is implemented.
@@ -929,6 +888,13 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
929
888
  throw e;
930
889
  }
931
890
  }
891
+ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode) {
892
+ if (!rootNode.output) {
893
+ return;
894
+ }
895
+ const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, state.context, event, actorCtx.self) : undefined);
896
+ return resolveOutput(rootNode.output, state.context, doneStateEvent, actorCtx.self);
897
+ }
932
898
  function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
933
899
  let nextState = currentState;
934
900
  const statesToEnter = new Set();
@@ -939,6 +905,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
939
905
  if (isInitial) {
940
906
  statesForDefaultEntry.add(currentState.machine.root);
941
907
  }
908
+ const completedNodes = new Set();
942
909
  for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
943
910
  mutConfiguration.add(stateNodeToEnter);
944
911
  const actions = [];
@@ -949,26 +916,34 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
949
916
  actions.push(invoke(invokeDef));
950
917
  }
951
918
  if (statesForDefaultEntry.has(stateNodeToEnter)) {
952
- for (const stateNode of statesForDefaultEntry) {
953
- const initialActions = stateNode.initial.actions;
954
- actions.push(...initialActions);
955
- }
919
+ const initialActions = stateNodeToEnter.initial.actions;
920
+ actions.push(...initialActions);
956
921
  }
957
922
  nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
958
923
  if (stateNodeToEnter.type === 'final') {
959
924
  const parent = stateNodeToEnter.parent;
960
- if (!parent.parent) {
925
+ if (completedNodes.has(parent)) {
961
926
  continue;
962
927
  }
963
- internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
964
- if (parent.parent) {
965
- const grandparent = parent.parent;
966
- if (grandparent.type === 'parallel') {
967
- if (getChildren(grandparent).every(parentNode => isInFinalState([...mutConfiguration], parentNode))) {
968
- internalQueue.push(createDoneStateEvent(grandparent.id));
969
- }
928
+ completedNodes.add(parent);
929
+ let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
930
+ let ancestorMarker = parent?.parent;
931
+ if (ancestorMarker) {
932
+ internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
933
+ while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
934
+ completedNodes.add(ancestorMarker);
935
+ internalQueue.push(createDoneStateEvent(ancestorMarker.id));
936
+ rootCompletionNode = ancestorMarker;
937
+ ancestorMarker = ancestorMarker.parent;
970
938
  }
971
939
  }
940
+ if (ancestorMarker) {
941
+ continue;
942
+ }
943
+ nextState = cloneState(nextState, {
944
+ status: 'done',
945
+ output: getMachineOutput(nextState, event, actorCtx, currentState.configuration[0].machine.root, rootCompletionNode)
946
+ });
972
947
  }
973
948
  }
974
949
  return nextState;
@@ -1014,13 +989,9 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1014
989
  statesToEnter.add(stateNode);
1015
990
  if (stateNode.type === 'compound') {
1016
991
  statesForDefaultEntry.add(stateNode);
1017
- const initialStates = stateNode.initial.target;
1018
- for (const initialState of initialStates) {
1019
- addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1020
- }
1021
- for (const initialState of initialStates) {
1022
- addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1023
- }
992
+ const [initialState] = stateNode.initial.target;
993
+ addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
994
+ addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1024
995
  } else {
1025
996
  if (stateNode.type === 'parallel') {
1026
997
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
@@ -1408,6 +1379,7 @@ function getPersistedState(state) {
1408
1379
  tags,
1409
1380
  machine,
1410
1381
  children,
1382
+ context,
1411
1383
  ...jsonValues
1412
1384
  } = state;
1413
1385
  const childrenJson = {};
@@ -1420,9 +1392,38 @@ function getPersistedState(state) {
1420
1392
  }
1421
1393
  return {
1422
1394
  ...jsonValues,
1395
+ // TODO: this makes `PersistedMachineState`'s type kind of a lie
1396
+ // it doesn't truly use `TContext` but rather some kind of a derived form of it
1397
+ context: persistContext(context),
1423
1398
  children: childrenJson
1424
1399
  };
1425
1400
  }
1401
+ function persistContext(contextPart) {
1402
+ let copy;
1403
+ for (const key in contextPart) {
1404
+ const value = contextPart[key];
1405
+ if (value && typeof value === 'object') {
1406
+ if ('sessionId' in value && 'send' in value && 'ref' in value) {
1407
+ copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
1408
+ ...contextPart
1409
+ };
1410
+ copy[key] = {
1411
+ xstate$$type: $$ACTOR_TYPE,
1412
+ id: value.id
1413
+ };
1414
+ } else {
1415
+ const result = persistContext(value);
1416
+ if (result !== value) {
1417
+ copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
1418
+ ...contextPart
1419
+ };
1420
+ copy[key] = result;
1421
+ }
1422
+ }
1423
+ }
1424
+ }
1425
+ return copy ?? contextPart;
1426
+ }
1426
1427
 
1427
1428
  function resolveRaise(_, state, args, {
1428
1429
  event: eventOrExpr,
@@ -1473,4 +1474,4 @@ function raise(eventOrExpr, options) {
1473
1474
  return raise;
1474
1475
  }
1475
1476
 
1476
- export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, isAtomicStateNode as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
1477
+ export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, getInitialStateNodes as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };