@likec4/diagram 1.55.1 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/dist/LikeC4Diagram.js +150 -194
  2. package/dist/LikeC4ModelProvider.js +13 -9
  3. package/dist/LikeC4ProjectsOverview.js +24 -30
  4. package/dist/LikeC4ProjectsProvider.js +33 -26
  5. package/dist/LikeC4Styles.js +40 -57
  6. package/dist/LikeC4View.js +148 -196
  7. package/dist/ReactLikeC4.js +43 -65
  8. package/dist/StaticLikeC4Diagram.js +36 -41
  9. package/dist/_virtual/_rolldown/runtime.js +17 -0
  10. package/dist/adhoc-editor/EditorPanel.js +102 -101
  11. package/dist/adhoc-editor/ElementsTree.js +109 -139
  12. package/dist/adhoc-editor/LikeC4AdHocViewEditor.js +77 -70
  13. package/dist/adhoc-editor/components/Tree.d.ts +2 -2
  14. package/dist/adhoc-editor/components/Tree.js +205 -288
  15. package/dist/adhoc-editor/hooks.js +28 -23
  16. package/dist/adhoc-editor/index.js +2 -1
  17. package/dist/adhoc-editor/state/ActorProvider.js +33 -36
  18. package/dist/adhoc-editor/state/actor.editor.js +148 -186
  19. package/dist/adhoc-editor/state/actor.js +12 -14
  20. package/dist/adhoc-editor/state/actor.layouter.js +49 -65
  21. package/dist/adhoc-editor/state/actor.types.js +19 -23
  22. package/dist/adhoc-editor/state/panel.js +112 -127
  23. package/dist/adhoc-editor/state/utils.js +22 -29
  24. package/dist/adhoc-editor/useElementsTree.js +89 -121
  25. package/dist/base/Background.js +26 -29
  26. package/dist/base/Base.js +34 -41
  27. package/dist/base/BaseXYFlow.js +135 -165
  28. package/dist/base/const.js +18 -19
  29. package/dist/base/updateEdges.js +38 -57
  30. package/dist/base/updateNodes.js +46 -65
  31. package/dist/base-primitives/Markdown.d.ts +1 -1
  32. package/dist/base-primitives/Markdown.js +32 -47
  33. package/dist/base-primitives/NodeHandles.js +39 -49
  34. package/dist/base-primitives/compound/CompoundActionButton.js +49 -69
  35. package/dist/base-primitives/compound/CompoundDetailsButton.js +39 -64
  36. package/dist/base-primitives/compound/CompoundNodeContainer.js +46 -66
  37. package/dist/base-primitives/compound/CompoundTitle.js +15 -12
  38. package/dist/base-primitives/compound/actionbtns.css.js +9 -18
  39. package/dist/base-primitives/edge/EdgeActionButton.js +17 -19
  40. package/dist/base-primitives/edge/EdgeContainer.js +29 -48
  41. package/dist/base-primitives/edge/EdgeLabel.js +44 -65
  42. package/dist/base-primitives/edge/EdgeLabelContainer.js +35 -73
  43. package/dist/base-primitives/edge/EdgeMarkers.js +157 -215
  44. package/dist/base-primitives/edge/EdgePath.js +62 -115
  45. package/dist/base-primitives/element/ElementActionButtons.js +92 -81
  46. package/dist/base-primitives/element/ElementData.js +107 -126
  47. package/dist/base-primitives/element/ElementDetailsButton.js +78 -98
  48. package/dist/base-primitives/element/ElementNodeContainer.js +51 -82
  49. package/dist/base-primitives/element/ElementShape.js +331 -317
  50. package/dist/base-primitives/element/ElementTags.d.ts +1 -1
  51. package/dist/base-primitives/element/ElementTags.js +133 -193
  52. package/dist/base-primitives/memoEdge.js +11 -10
  53. package/dist/base-primitives/memoNode.js +16 -20
  54. package/dist/components/ErrorFallback.js +111 -75
  55. package/dist/components/GithubIcon.js +14 -16
  56. package/dist/components/Link.js +99 -113
  57. package/dist/components/Logo.js +38 -41
  58. package/dist/components/NavigationLink.js +15 -23
  59. package/dist/components/NavigationPanel.js +26 -47
  60. package/dist/components/PortalToContainer.js +16 -10
  61. package/dist/components/RootContainer.js +36 -31
  62. package/dist/components/SearchControl.css.js +65 -75
  63. package/dist/components/SearchControl.js +36 -14
  64. package/dist/components/ViewNotFound.js +22 -29
  65. package/dist/context/CurrentViewModelProvider.js +11 -9
  66. package/dist/context/DefaultMantineProvider.js +45 -72
  67. package/dist/context/DiagramEventHandlers.js +43 -48
  68. package/dist/context/DiagramFeatures.d.ts +1 -1
  69. package/dist/context/DiagramFeatures.js +78 -69
  70. package/dist/context/EnsureMantine.js +13 -16
  71. package/dist/context/FramerMotionConfig.js +17 -11
  72. package/dist/context/IconRenderer.js +90 -106
  73. package/dist/context/LikeC4ModelContext.js +14 -10
  74. package/dist/context/LikeC4ProjectsContext.js +7 -6
  75. package/dist/context/RootContainerContext.d.ts +9 -19
  76. package/dist/context/RootContainerContext.js +14 -28
  77. package/dist/context/TagStylesContext.js +49 -57
  78. package/dist/custom/customNodes.js +224 -28
  79. package/dist/custom/index.d.ts +1 -1
  80. package/dist/custom/index.js +40 -40
  81. package/dist/editor/LikeC4EditorCallbacks.d.ts +5 -0
  82. package/dist/editor/LikeC4EditorCallbacks.js +4 -2
  83. package/dist/editor/LikeC4EditorProvider.js +32 -7
  84. package/dist/editor/actor/actions.d.ts +115 -0
  85. package/dist/editor/actor/actions.js +122 -0
  86. package/dist/editor/{hotkeyActor.d.ts → actor/hotkey.d.ts} +1 -1
  87. package/dist/editor/actor/hotkey.js +20 -0
  88. package/dist/editor/actor/machine.d.ts +11 -0
  89. package/dist/editor/actor/machine.js +22 -0
  90. package/dist/editor/{editorActor.setup.d.ts → actor/setup.d.ts} +13 -49
  91. package/dist/editor/actor/setup.js +35 -0
  92. package/dist/editor/actor/state.editor.d.ts +97 -0
  93. package/dist/editor/actor/state.editor.js +55 -0
  94. package/dist/editor/actor/state.sync-queue.d.ts +420 -0
  95. package/dist/editor/actor/state.sync-queue.js +235 -0
  96. package/dist/editor/actor/types.d.ts +59 -0
  97. package/dist/editor/actor/types.js +5 -0
  98. package/dist/editor/applyChangesToManualLayout.js +144 -163
  99. package/dist/editor/index.d.ts +2 -1
  100. package/dist/editor/useEditorActorLogic.d.ts +8 -2
  101. package/dist/editor/useEditorActorLogic.js +51 -43
  102. package/dist/hooks/safeContext.js +17 -17
  103. package/dist/hooks/useCallbackRef.js +18 -11
  104. package/dist/hooks/useCurrentView.js +16 -7
  105. package/dist/hooks/useCurrentViewModel.js +14 -9
  106. package/dist/hooks/useDiagram.js +60 -37
  107. package/dist/hooks/useDiagramCompareLayout.js +77 -81
  108. package/dist/hooks/useEditorActor.d.ts +4 -0
  109. package/dist/hooks/useEditorActor.js +26 -0
  110. package/dist/hooks/useId.js +8 -6
  111. package/dist/hooks/useLikeC4ElementsTree.d.ts +3 -2
  112. package/dist/hooks/useLikeC4ElementsTree.js +24 -21
  113. package/dist/hooks/useLikeC4Model.js +21 -20
  114. package/dist/hooks/useLikeC4Project.js +40 -29
  115. package/dist/hooks/useLikeC4Styles.js +6 -6
  116. package/dist/hooks/useMantinePortalProps.js +10 -6
  117. package/dist/hooks/useSetState.js +21 -19
  118. package/dist/hooks/useUpdateEffect.js +18 -29
  119. package/dist/hooks/useXYFlow.js +13 -15
  120. package/dist/index.js +24 -23
  121. package/dist/likec4diagram/DiagramUI.js +37 -37
  122. package/dist/likec4diagram/DiagramXYFlow.js +215 -224
  123. package/dist/likec4diagram/convert-to-xyflow.js +21 -22
  124. package/dist/likec4diagram/custom/edges/EdgeDrifts.js +22 -32
  125. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +275 -372
  126. package/dist/likec4diagram/custom/edges/SequenceStepEdge.js +71 -75
  127. package/dist/likec4diagram/custom/edges/edges.css.js +41 -47
  128. package/dist/likec4diagram/custom/edges/useControlPoints.js +52 -56
  129. package/dist/likec4diagram/custom/edges/useRelationshipEdgePath.js +54 -76
  130. package/dist/likec4diagram/custom/index.js +17 -17
  131. package/dist/likec4diagram/custom/nodes/CompoundActions.js +19 -26
  132. package/dist/likec4diagram/custom/nodes/ElementActions.js +131 -82
  133. package/dist/likec4diagram/custom/nodes/NodeDrifts.js +20 -26
  134. package/dist/likec4diagram/custom/nodes/NodeNotes.js +215 -273
  135. package/dist/likec4diagram/custom/nodes/SequenceActorNode.js +131 -147
  136. package/dist/likec4diagram/custom/nodes/nodes.js +135 -146
  137. package/dist/likec4diagram/custom/nodes/toolbar/ColorButton.js +155 -159
  138. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +58 -86
  139. package/dist/likec4diagram/custom/nodes/toolbar/ElementToolbar.js +108 -164
  140. package/dist/likec4diagram/custom/nodes/toolbar/Toolbar.js +56 -68
  141. package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +3 -6
  142. package/dist/likec4diagram/custom/nodes/toolbar/_shared.js +97 -102
  143. package/dist/likec4diagram/custom/nodes/toolbar/styles.css.js +13 -13
  144. package/dist/likec4diagram/custom/nodes/toolbar/types.js +6 -5
  145. package/dist/likec4diagram/custom/nodes/toolbar/useHandlers.js +36 -41
  146. package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +510 -541
  147. package/dist/likec4diagram/relationship-popover/actor.js +113 -152
  148. package/dist/likec4diagram/relationship-popover/components.js +39 -43
  149. package/dist/likec4diagram/state/DiagramActorProvider.js +135 -136
  150. package/dist/likec4diagram/state/aligners.js +286 -360
  151. package/dist/likec4diagram/state/assign.js +84 -108
  152. package/dist/likec4diagram/state/createViewChange.js +72 -92
  153. package/dist/likec4diagram/state/diagram-api.d.ts +16 -0
  154. package/dist/likec4diagram/state/diagram-api.js +230 -152
  155. package/dist/likec4diagram/state/hotkeyActor.js +54 -45
  156. package/dist/likec4diagram/state/machine.actions.js +708 -821
  157. package/dist/likec4diagram/state/machine.actions.layout.js +154 -183
  158. package/dist/likec4diagram/state/machine.d.ts +1 -1
  159. package/dist/likec4diagram/state/machine.js +113 -134
  160. package/dist/likec4diagram/state/machine.setup.js +104 -113
  161. package/dist/likec4diagram/state/machine.state.initializing.js +54 -54
  162. package/dist/likec4diagram/state/machine.state.navigating.js +192 -227
  163. package/dist/likec4diagram/state/machine.state.ready.focused.js +72 -88
  164. package/dist/likec4diagram/state/machine.state.ready.idle.js +79 -98
  165. package/dist/likec4diagram/state/machine.state.ready.js +126 -202
  166. package/dist/likec4diagram/state/machine.state.ready.printing.js +38 -39
  167. package/dist/likec4diagram/state/machine.state.ready.walkthrough.js +153 -193
  168. package/dist/likec4diagram/state/mediaPrintActor.js +20 -16
  169. package/dist/likec4diagram/state/persistence.js +20 -21
  170. package/dist/likec4diagram/state/types.d.ts +1 -1
  171. package/dist/likec4diagram/state/utils.d.ts +1 -1
  172. package/dist/likec4diagram/state/utils.js +131 -162
  173. package/dist/likec4diagram/ui/LayoutDriftFrame.js +53 -64
  174. package/dist/likec4diagram/ui/notation/NotationPanel.css.js +58 -80
  175. package/dist/likec4diagram/ui/notation/NotationPanel.js +183 -214
  176. package/dist/likec4diagram/useLayoutConstraints.js +388 -433
  177. package/dist/likec4diagram/xyflow-diagram/diagram-view.js +216 -227
  178. package/dist/likec4diagram/xyflow-sequence/const.js +11 -7
  179. package/dist/likec4diagram/xyflow-sequence/sequence-layout.js +177 -180
  180. package/dist/navigationpanel/NavigationPanel.js +113 -123
  181. package/dist/navigationpanel/NavigationPanelControls.js +124 -150
  182. package/dist/navigationpanel/NavigationPanelDropdown.js +365 -477
  183. package/dist/navigationpanel/_common.d.ts +4 -10
  184. package/dist/navigationpanel/_common.js +57 -70
  185. package/dist/navigationpanel/actor.js +153 -236
  186. package/dist/navigationpanel/comparepanel/CompareActionsMenu.js +66 -83
  187. package/dist/navigationpanel/comparepanel/ComparePanel.js +135 -164
  188. package/dist/navigationpanel/comparepanel/ComparePanelControls.js +50 -58
  189. package/dist/navigationpanel/comparepanel/DriftsSummary.js +207 -254
  190. package/dist/navigationpanel/comparepanel/LayoutTypeSwitcher.js +33 -35
  191. package/dist/navigationpanel/controls/DetailsControls.js +219 -246
  192. package/dist/navigationpanel/controls/LayoutWarning.js +89 -100
  193. package/dist/navigationpanel/controls/LogoButton.js +46 -70
  194. package/dist/navigationpanel/controls/NavigationButtons.js +35 -52
  195. package/dist/navigationpanel/controls/OpenSource.js +27 -25
  196. package/dist/navigationpanel/controls/SearchControl.js +50 -61
  197. package/dist/navigationpanel/controls/ToggleReadonly.js +86 -81
  198. package/dist/navigationpanel/dropdown/ProjectsMenu.js +69 -87
  199. package/dist/navigationpanel/editorpanel/ApplySemanticLayout.d.ts +4 -0
  200. package/dist/navigationpanel/editorpanel/ApplySemanticLayout.js +36 -0
  201. package/dist/navigationpanel/editorpanel/CenterCamera.js +17 -13
  202. package/dist/navigationpanel/editorpanel/ChangeAutoLayoutButton.js +182 -154
  203. package/dist/navigationpanel/editorpanel/EditorPanel.js +59 -45
  204. package/dist/navigationpanel/editorpanel/ManualLayoutToolsButton.js +122 -173
  205. package/dist/navigationpanel/editorpanel/ToggleReadonly.js +20 -13
  206. package/dist/navigationpanel/editorpanel/_common.d.ts +3 -6
  207. package/dist/navigationpanel/editorpanel/_common.js +13 -13
  208. package/dist/navigationpanel/editorpanel/styles.js +58 -75
  209. package/dist/navigationpanel/hooks.js +35 -29
  210. package/dist/navigationpanel/styles.css.js +20 -28
  211. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.js +107 -134
  212. package/dist/navigationpanel/walkthrough/DynamicViewControls.d.ts +65 -65
  213. package/dist/navigationpanel/walkthrough/DynamicViewControls.js +105 -120
  214. package/dist/navigationpanel/walkthrough/WalkthroughPanel.js +75 -83
  215. package/dist/overlays/Overlays.js +94 -112
  216. package/dist/overlays/element-details/ElementDetails.js +22 -28
  217. package/dist/overlays/element-details/ElementDetailsCard.css.js +198 -221
  218. package/dist/overlays/element-details/ElementDetailsCard.js +517 -499
  219. package/dist/overlays/element-details/MetadataValue.js +210 -250
  220. package/dist/overlays/element-details/TabPanelDeployments.css.js +40 -60
  221. package/dist/overlays/element-details/TabPanelDeployments.js +185 -178
  222. package/dist/overlays/element-details/TabPanelRelationships.css.js +63 -71
  223. package/dist/overlays/element-details/TabPanelRelationships.js +155 -140
  224. package/dist/overlays/element-details/TabPanelStructure.css.js +29 -33
  225. package/dist/overlays/element-details/TabPanelStructure.js +93 -93
  226. package/dist/overlays/element-details/actor.js +45 -55
  227. package/dist/overlays/element-details/actorContext.js +12 -10
  228. package/dist/overlays/overlay/Overlay.d.ts +16 -0
  229. package/dist/overlays/overlay/Overlay.js +102 -151
  230. package/dist/overlays/overlaysActor.js +215 -265
  231. package/dist/overlays/relationship-details/RelationshipDetails.js +270 -253
  232. package/dist/overlays/relationship-details/SelectEdge.css.js +62 -74
  233. package/dist/overlays/relationship-details/SelectEdge.js +146 -126
  234. package/dist/overlays/relationship-details/actor.js +242 -303
  235. package/dist/overlays/relationship-details/compute.js +109 -135
  236. package/dist/overlays/relationship-details/custom/ElementActions.js +43 -56
  237. package/dist/overlays/relationship-details/custom/edgeTypes.js +43 -49
  238. package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +4 -5
  239. package/dist/overlays/relationship-details/custom/nodeTypes.js +96 -121
  240. package/dist/overlays/relationship-details/hooks.js +44 -38
  241. package/dist/overlays/relationship-details/layout-to-xyflow.js +119 -141
  242. package/dist/overlays/relationship-details/layout.js +275 -304
  243. package/dist/overlays/relationships-browser/RelationshipsBrowser.js +319 -321
  244. package/dist/overlays/relationships-browser/SelectElement.css.js +18 -21
  245. package/dist/overlays/relationships-browser/SelectElement.js +192 -218
  246. package/dist/overlays/relationships-browser/actor.js +364 -462
  247. package/dist/overlays/relationships-browser/const.js +7 -6
  248. package/dist/overlays/relationships-browser/custom/ElementActions.js +60 -63
  249. package/dist/overlays/relationships-browser/custom/EmptyNode.js +25 -29
  250. package/dist/overlays/relationships-browser/custom/edgeTypes.js +66 -99
  251. package/dist/overlays/relationships-browser/custom/nodeTypes.js +98 -123
  252. package/dist/overlays/relationships-browser/hooks.js +49 -51
  253. package/dist/overlays/relationships-browser/layout.js +413 -465
  254. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +141 -157
  255. package/dist/projects-overview/ProjectsOverview.js +56 -55
  256. package/dist/projects-overview/ProjectsOverviewXY.js +105 -94
  257. package/dist/projects-overview/actor.js +252 -345
  258. package/dist/projects-overview/context.js +8 -7
  259. package/dist/projects-overview/custom/edgeTypes.js +22 -21
  260. package/dist/projects-overview/custom/nodeTypes.js +38 -42
  261. package/dist/projects-overview/hooks.js +9 -9
  262. package/dist/projects-overview/layouted-to-xyflow.js +46 -42
  263. package/dist/projects-overview/panel/ProjectsOverviewPanel.js +7 -9
  264. package/dist/projects-overview/persistence.js +22 -22
  265. package/dist/search/Search.d.ts +6 -3
  266. package/dist/search/Search.js +189 -182
  267. package/dist/search/SearchContext.js +16 -15
  268. package/dist/search/XStateSearchAdapter.js +68 -62
  269. package/dist/search/components/ElementsColumn.css.js +50 -68
  270. package/dist/search/components/ElementsColumn.js +253 -291
  271. package/dist/search/components/PickView.js +116 -140
  272. package/dist/search/components/SearchByTags.js +76 -94
  273. package/dist/search/components/SearchInput.js +187 -209
  274. package/dist/search/components/ViewsColum.js +151 -141
  275. package/dist/search/components/ViewsColumn.css.js +12 -26
  276. package/dist/search/components/_shared.css.js +127 -153
  277. package/dist/search/components/styles.css.js +47 -53
  278. package/dist/search/components/utils.js +44 -47
  279. package/dist/search/hooks.js +10 -10
  280. package/dist/search/searchActor.js +97 -128
  281. package/dist/shadowroot/ShadowRoot.d.ts +7 -6
  282. package/dist/shadowroot/ShadowRoot.js +106 -79
  283. package/dist/shadowroot/styles.css.d.ts +10 -2
  284. package/dist/shadowroot/styles.css.js +56 -69
  285. package/dist/styles-font2.js +4 -0
  286. package/dist/styles2.js +4 -0
  287. package/dist/utils/index.js +5 -0
  288. package/dist/utils/roundDpr.js +19 -15
  289. package/dist/utils/view-bounds.js +48 -55
  290. package/dist/utils/xyflow.js +143 -113
  291. package/package.json +18 -25
  292. package/panda.buildinfo.json +15 -15
  293. package/src/styles-font.css +114 -0
  294. package/src/styles-min.css +2 -0
  295. package/src/styles-xyflow.css +1 -0
  296. package/src/styles.css +3 -0
  297. package/styles-font.css +1 -1
  298. package/styles-min.css +1 -1
  299. package/styles-xyflow.css +1 -1
  300. package/styles.css +1 -1
  301. package/dist/_virtual/_commonjsHelpers.js +0 -3
  302. package/dist/_virtual/assign-f10db67b.cjs.js +0 -3
  303. package/dist/_virtual/log-30abbb83.cjs.js +0 -3
  304. package/dist/_virtual/raise-f051f097.cjs.js +0 -3
  305. package/dist/_virtual/store-cfe7da62.cjs.js +0 -3
  306. package/dist/_virtual/xstate-actions.cjs.js +0 -5
  307. package/dist/_virtual/xstate-actions.cjs2.js +0 -3
  308. package/dist/_virtual/xstate-dev.cjs.js +0 -3
  309. package/dist/_virtual/xstate-guards.cjs.js +0 -5
  310. package/dist/_virtual/xstate-guards.cjs2.js +0 -3
  311. package/dist/_virtual/xstate-store-react.cjs.js +0 -5
  312. package/dist/_virtual/xstate-store-react.cjs2.js +0 -3
  313. package/dist/bundle/index.d.ts +0 -1
  314. package/dist/editor/editorActor.actions.d.ts +0 -153
  315. package/dist/editor/editorActor.actions.js +0 -149
  316. package/dist/editor/editorActor.setup.js +0 -38
  317. package/dist/editor/editorActor.states.d.ts +0 -9
  318. package/dist/editor/editorActor.states.js +0 -273
  319. package/dist/editor/hotkeyActor.js +0 -19
  320. package/dist/hooks/useOverlaysActor.js +0 -10
  321. package/dist/hooks/useSearchActor.js +0 -10
  322. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/createReactComponent.js +0 -41
  323. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.js +0 -30
  324. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconAlertTriangle.js +0 -14
  325. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowDownRight.js +0 -14
  326. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowLeft.js +0 -14
  327. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowRight.js +0 -14
  328. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconBolt.js +0 -14
  329. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconBrowser.js +0 -14
  330. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.js +0 -14
  331. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronDown.js +0 -14
  332. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.js +0 -14
  333. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.js +0 -14
  334. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.js +0 -14
  335. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconCylinder.js +0 -14
  336. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconDeviceMobile.js +0 -14
  337. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconDirectionSignFilled.js +0 -14
  338. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconExternalLink.js +0 -14
  339. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconFileSymlink.js +0 -14
  340. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconFileText.js +0 -14
  341. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconFocusCentered.js +0 -14
  342. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconFolderFilled.js +0 -14
  343. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconHelpCircle.js +0 -14
  344. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconId.js +0 -14
  345. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconInfoCircle.js +0 -14
  346. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutAlignBottom.js +0 -14
  347. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutAlignCenter.js +0 -14
  348. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutAlignLeft.js +0 -14
  349. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutAlignMiddle.js +0 -14
  350. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutAlignRight.js +0 -14
  351. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutAlignTop.js +0 -14
  352. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutBoardSplit.js +0 -14
  353. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutCollage.js +0 -14
  354. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLayoutDashboard.js +0 -14
  355. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLink.js +0 -14
  356. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLock.js +0 -14
  357. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconLockOpen2.js +0 -14
  358. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconPlayerPlayFilled.js +0 -14
  359. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconPlayerSkipBackFilled.js +0 -14
  360. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconPlayerSkipForwardFilled.js +0 -14
  361. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconPlayerStopFilled.js +0 -14
  362. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconRectangularPrism.js +0 -14
  363. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconReorder.js +0 -14
  364. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconRouteOff.js +0 -14
  365. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.js +0 -14
  366. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconSelector.js +0 -14
  367. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconStack2.js +0 -14
  368. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconStarFilled.js +0 -14
  369. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconTarget.js +0 -14
  370. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconTransform.js +0 -14
  371. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconTrash.js +0 -14
  372. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconUser.js +0 -14
  373. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconX.js +0 -14
  374. package/dist/node_modules/.pnpm/@tabler_icons-react@3.40.0_react@19.2.4/node_modules/@tabler/icons-react/dist/esm/icons/IconZoomScan.js +0 -14
  375. package/dist/node_modules/.pnpm/@xstate_store@3.17.1_react@19.2.4/node_modules/@xstate/store/dist/store-cfe7da62.cjs.js +0 -761
  376. package/dist/node_modules/.pnpm/@xstate_store@3.17.1_react@19.2.4/node_modules/@xstate/store/react/dist/xstate-store-react.cjs.js +0 -180
  377. package/dist/node_modules/.pnpm/xstate@5.30.0/node_modules/xstate/actions/dist/xstate-actions.cjs.js +0 -37
  378. package/dist/node_modules/.pnpm/xstate@5.30.0/node_modules/xstate/dev/dist/xstate-dev.cjs.js +0 -59
  379. package/dist/node_modules/.pnpm/xstate@5.30.0/node_modules/xstate/dist/assign-f10db67b.cjs.js +0 -140
  380. package/dist/node_modules/.pnpm/xstate@5.30.0/node_modules/xstate/dist/log-30abbb83.cjs.js +0 -401
  381. package/dist/node_modules/.pnpm/xstate@5.30.0/node_modules/xstate/dist/raise-f051f097.cjs.js +0 -2830
  382. package/dist/node_modules/.pnpm/xstate@5.30.0/node_modules/xstate/guards/dist/xstate-guards.cjs.js +0 -26
  383. package/dist/styles-font.css2.js +0 -3
  384. package/dist/styles.css2.js +0 -3
@@ -1,2830 +0,0 @@
1
- import { __exports as raiseF051f097_cjs } from '../../../../../../_virtual/raise-f051f097.cjs.js';
2
- import { __require as requireXstateDev_cjs } from '../dev/dist/xstate-dev.cjs.js';
3
-
4
- var hasRequiredRaiseF051f097_cjs;
5
-
6
- function requireRaiseF051f097_cjs () {
7
- if (hasRequiredRaiseF051f097_cjs) return raiseF051f097_cjs;
8
- hasRequiredRaiseF051f097_cjs = 1;
9
-
10
- var dev_dist_xstateDev = requireXstateDev_cjs();
11
-
12
- class Mailbox {
13
- constructor(_process) {
14
- this._process = _process;
15
- this._active = false;
16
- this._current = null;
17
- this._last = null;
18
- }
19
- start() {
20
- this._active = true;
21
- this.flush();
22
- }
23
- clear() {
24
- // we can't set _current to null because we might be currently processing
25
- // and enqueue following clear shouldn't start processing the enqueued item immediately
26
- if (this._current) {
27
- this._current.next = null;
28
- this._last = this._current;
29
- }
30
- }
31
- enqueue(event) {
32
- const enqueued = {
33
- value: event,
34
- next: null
35
- };
36
- if (this._current) {
37
- this._last.next = enqueued;
38
- this._last = enqueued;
39
- return;
40
- }
41
- this._current = enqueued;
42
- this._last = enqueued;
43
- if (this._active) {
44
- this.flush();
45
- }
46
- }
47
- flush() {
48
- while (this._current) {
49
- // atm the given _process is responsible for implementing proper try/catch handling
50
- // we assume here that this won't throw in a way that can affect this mailbox
51
- const consumed = this._current;
52
- this._process(consumed.value);
53
- this._current = consumed.next;
54
- }
55
- this._last = null;
56
- }
57
- }
58
-
59
- const STATE_DELIMITER = '.';
60
- const TARGETLESS_KEY = '';
61
- const NULL_EVENT = '';
62
- const STATE_IDENTIFIER = '#';
63
- const WILDCARD = '*';
64
- const XSTATE_INIT = 'xstate.init';
65
- const XSTATE_ERROR = 'xstate.error';
66
- const XSTATE_STOP = 'xstate.stop';
67
-
68
- /**
69
- * Returns an event that represents an implicit event that is sent after the
70
- * specified `delay`.
71
- *
72
- * @param delayRef The delay in milliseconds
73
- * @param id The state node ID where this event is handled
74
- */
75
- function createAfterEvent(delayRef, id) {
76
- return {
77
- type: `xstate.after.${delayRef}.${id}`
78
- };
79
- }
80
-
81
- /**
82
- * Returns an event that represents that a final state node has been reached in
83
- * the parent state node.
84
- *
85
- * @param id The final state node's parent state node `id`
86
- * @param output The data to pass into the event
87
- */
88
- function createDoneStateEvent(id, output) {
89
- return {
90
- type: `xstate.done.state.${id}`,
91
- output
92
- };
93
- }
94
-
95
- /**
96
- * Returns an event that represents that an invoked service has terminated.
97
- *
98
- * An invoked service is terminated when it has reached a top-level final state
99
- * node, but not when it is canceled.
100
- *
101
- * @param invokeId The invoked service ID
102
- * @param output The data to pass into the event
103
- */
104
- function createDoneActorEvent(invokeId, output) {
105
- return {
106
- type: `xstate.done.actor.${invokeId}`,
107
- output,
108
- actorId: invokeId
109
- };
110
- }
111
- function createErrorActorEvent(id, error) {
112
- return {
113
- type: `xstate.error.actor.${id}`,
114
- error,
115
- actorId: id
116
- };
117
- }
118
- function createInitEvent(input) {
119
- return {
120
- type: XSTATE_INIT,
121
- input
122
- };
123
- }
124
-
125
- /**
126
- * This function makes sure that unhandled errors are thrown in a separate
127
- * macrotask. It allows those errors to be detected by global error handlers and
128
- * reported to bug tracking services without interrupting our own stack of
129
- * execution.
130
- *
131
- * @param err Error to be thrown
132
- */
133
- function reportUnhandledError(err) {
134
- setTimeout(() => {
135
- throw err;
136
- });
137
- }
138
-
139
- const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
140
-
141
- function matchesState(parentStateId, childStateId) {
142
- const parentStateValue = toStateValue(parentStateId);
143
- const childStateValue = toStateValue(childStateId);
144
- if (typeof childStateValue === 'string') {
145
- if (typeof parentStateValue === 'string') {
146
- return childStateValue === parentStateValue;
147
- }
148
-
149
- // Parent more specific than child
150
- return false;
151
- }
152
- if (typeof parentStateValue === 'string') {
153
- return parentStateValue in childStateValue;
154
- }
155
- return Object.keys(parentStateValue).every(key => {
156
- if (!(key in childStateValue)) {
157
- return false;
158
- }
159
- return matchesState(parentStateValue[key], childStateValue[key]);
160
- });
161
- }
162
- function toStatePath(stateId) {
163
- if (isArray(stateId)) {
164
- return stateId;
165
- }
166
- const result = [];
167
- let segment = '';
168
- for (let i = 0; i < stateId.length; i++) {
169
- const char = stateId.charCodeAt(i);
170
- switch (char) {
171
- // \
172
- case 92:
173
- // consume the next character
174
- segment += stateId[i + 1];
175
- // and skip over it
176
- i++;
177
- continue;
178
- // .
179
- case 46:
180
- result.push(segment);
181
- segment = '';
182
- continue;
183
- }
184
- segment += stateId[i];
185
- }
186
- result.push(segment);
187
- return result;
188
- }
189
- function toStateValue(stateValue) {
190
- if (isMachineSnapshot(stateValue)) {
191
- return stateValue.value;
192
- }
193
- if (typeof stateValue !== 'string') {
194
- return stateValue;
195
- }
196
- const statePath = toStatePath(stateValue);
197
- return pathToStateValue(statePath);
198
- }
199
- function pathToStateValue(statePath) {
200
- if (statePath.length === 1) {
201
- return statePath[0];
202
- }
203
- const value = {};
204
- let marker = value;
205
- for (let i = 0; i < statePath.length - 1; i++) {
206
- if (i === statePath.length - 2) {
207
- marker[statePath[i]] = statePath[i + 1];
208
- } else {
209
- const previous = marker;
210
- marker = {};
211
- previous[statePath[i]] = marker;
212
- }
213
- }
214
- return value;
215
- }
216
- function mapValues(collection, iteratee) {
217
- const result = {};
218
- const collectionKeys = Object.keys(collection);
219
- for (let i = 0; i < collectionKeys.length; i++) {
220
- const key = collectionKeys[i];
221
- result[key] = iteratee(collection[key], key, collection, i);
222
- }
223
- return result;
224
- }
225
- function toArrayStrict(value) {
226
- if (isArray(value)) {
227
- return value;
228
- }
229
- return [value];
230
- }
231
- function toArray(value) {
232
- if (value === undefined) {
233
- return [];
234
- }
235
- return toArrayStrict(value);
236
- }
237
- function resolveOutput(mapper, context, event, self) {
238
- if (typeof mapper === 'function') {
239
- return mapper({
240
- context,
241
- event,
242
- self
243
- });
244
- }
245
- return mapper;
246
- }
247
- function isArray(value) {
248
- return Array.isArray(value);
249
- }
250
- function isErrorActorEvent(event) {
251
- return event.type.startsWith('xstate.error.actor');
252
- }
253
- function toTransitionConfigArray(configLike) {
254
- return toArrayStrict(configLike).map(transitionLike => {
255
- if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
256
- return {
257
- target: transitionLike
258
- };
259
- }
260
- return transitionLike;
261
- });
262
- }
263
- function normalizeTarget(target) {
264
- if (target === undefined || target === TARGETLESS_KEY) {
265
- return undefined;
266
- }
267
- return toArray(target);
268
- }
269
- function toObserver(nextHandler, errorHandler, completionHandler) {
270
- const isObserver = typeof nextHandler === 'object';
271
- const self = isObserver ? nextHandler : undefined;
272
- return {
273
- next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
274
- error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
275
- complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(self)
276
- };
277
- }
278
- function createInvokeId(stateNodeId, index) {
279
- return `${index}.${stateNodeId}`;
280
- }
281
- function resolveReferencedActor(machine, src) {
282
- const match = src.match(/^xstate\.invoke\.(\d+)\.(.*)/);
283
- if (!match) {
284
- return machine.implementations.actors[src];
285
- }
286
- const [, indexStr, nodeId] = match;
287
- const node = machine.getStateNodeById(nodeId);
288
- const invokeConfig = node.config.invoke;
289
- return (Array.isArray(invokeConfig) ? invokeConfig[indexStr] : invokeConfig).src;
290
- }
291
- function getAllOwnEventDescriptors(snapshot) {
292
- return [...new Set([...snapshot._nodes.flatMap(sn => sn.ownEvents)])];
293
- }
294
-
295
- /**
296
- * Checks if an event type matches an event descriptor, supporting wildcards.
297
- * Event descriptors can be:
298
- *
299
- * - Exact matches: "event.type"
300
- * - Wildcard: "*"
301
- * - Partial matches: "event.*"
302
- *
303
- * @param eventType - The actual event type string
304
- * @param descriptor - The event descriptor to match against
305
- * @returns True if the event type matches the descriptor
306
- */
307
- function matchesEventDescriptor(eventType, descriptor) {
308
- if (descriptor === eventType) {
309
- return true;
310
- }
311
- if (descriptor === WILDCARD) {
312
- return true;
313
- }
314
- if (!descriptor.endsWith('.*')) {
315
- return false;
316
- }
317
- const partialEventTokens = descriptor.split('.');
318
- const eventTokens = eventType.split('.');
319
- for (let tokenIndex = 0; tokenIndex < partialEventTokens.length; tokenIndex++) {
320
- const partialEventToken = partialEventTokens[tokenIndex];
321
- const eventToken = eventTokens[tokenIndex];
322
- if (partialEventToken === '*') {
323
- const isLastToken = tokenIndex === partialEventTokens.length - 1;
324
- return isLastToken;
325
- }
326
- if (partialEventToken !== eventToken) {
327
- return false;
328
- }
329
- }
330
- return true;
331
- }
332
-
333
- function createScheduledEventId(actorRef, id) {
334
- return `${actorRef.sessionId}.${id}`;
335
- }
336
- let idCounter = 0;
337
- function createSystem(rootActor, options) {
338
- const children = new Map();
339
- const keyedActors = new Map();
340
- const reverseKeyedActors = new WeakMap();
341
- const inspectionObservers = new Set();
342
- const timerMap = {};
343
- const {
344
- clock,
345
- logger
346
- } = options;
347
- const scheduler = {
348
- schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
349
- const scheduledEvent = {
350
- source,
351
- target,
352
- event,
353
- delay,
354
- id,
355
- startedAt: Date.now()
356
- };
357
- const scheduledEventId = createScheduledEventId(source, id);
358
- system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
359
- const timeout = clock.setTimeout(() => {
360
- delete timerMap[scheduledEventId];
361
- delete system._snapshot._scheduledEvents[scheduledEventId];
362
- system._relay(source, target, event);
363
- }, delay);
364
- timerMap[scheduledEventId] = timeout;
365
- },
366
- cancel: (source, id) => {
367
- const scheduledEventId = createScheduledEventId(source, id);
368
- const timeout = timerMap[scheduledEventId];
369
- delete timerMap[scheduledEventId];
370
- delete system._snapshot._scheduledEvents[scheduledEventId];
371
- if (timeout !== undefined) {
372
- clock.clearTimeout(timeout);
373
- }
374
- },
375
- cancelAll: actorRef => {
376
- for (const scheduledEventId in system._snapshot._scheduledEvents) {
377
- const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
378
- if (scheduledEvent.source === actorRef) {
379
- scheduler.cancel(actorRef, scheduledEvent.id);
380
- }
381
- }
382
- }
383
- };
384
- const sendInspectionEvent = event => {
385
- if (!inspectionObservers.size) {
386
- return;
387
- }
388
- const resolvedInspectionEvent = {
389
- ...event,
390
- rootId: rootActor.sessionId
391
- };
392
- inspectionObservers.forEach(observer => observer.next?.(resolvedInspectionEvent));
393
- };
394
- const system = {
395
- _snapshot: {
396
- _scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {}
397
- },
398
- _bookId: () => `x:${idCounter++}`,
399
- _register: (sessionId, actorRef) => {
400
- children.set(sessionId, actorRef);
401
- return sessionId;
402
- },
403
- _unregister: actorRef => {
404
- children.delete(actorRef.sessionId);
405
- const systemId = reverseKeyedActors.get(actorRef);
406
- if (systemId !== undefined) {
407
- keyedActors.delete(systemId);
408
- reverseKeyedActors.delete(actorRef);
409
- }
410
- },
411
- get: systemId => {
412
- return keyedActors.get(systemId);
413
- },
414
- getAll: () => {
415
- return Object.fromEntries(keyedActors.entries());
416
- },
417
- _set: (systemId, actorRef) => {
418
- const existing = keyedActors.get(systemId);
419
- if (existing && existing !== actorRef) {
420
- throw new Error(`Actor with system ID '${systemId}' already exists.`);
421
- }
422
- keyedActors.set(systemId, actorRef);
423
- reverseKeyedActors.set(actorRef, systemId);
424
- },
425
- inspect: observerOrFn => {
426
- const observer = toObserver(observerOrFn);
427
- inspectionObservers.add(observer);
428
- return {
429
- unsubscribe() {
430
- inspectionObservers.delete(observer);
431
- }
432
- };
433
- },
434
- _sendInspectionEvent: sendInspectionEvent,
435
- _relay: (source, target, event) => {
436
- system._sendInspectionEvent({
437
- type: '@xstate.event',
438
- sourceRef: source,
439
- actorRef: target,
440
- event
441
- });
442
- target._send(event);
443
- },
444
- scheduler,
445
- getSnapshot: () => {
446
- return {
447
- _scheduledEvents: {
448
- ...system._snapshot._scheduledEvents
449
- }
450
- };
451
- },
452
- start: () => {
453
- const scheduledEvents = system._snapshot._scheduledEvents;
454
- system._snapshot._scheduledEvents = {};
455
- for (const scheduledId in scheduledEvents) {
456
- const {
457
- source,
458
- target,
459
- event,
460
- delay,
461
- id
462
- } = scheduledEvents[scheduledId];
463
- scheduler.schedule(source, target, event, delay, id);
464
- }
465
- },
466
- _clock: clock,
467
- _logger: logger
468
- };
469
- return system;
470
- }
471
-
472
- // those are needed to make JSDoc `@link` work properly
473
-
474
- let executingCustomAction = false;
475
- const $$ACTOR_TYPE = 1;
476
-
477
- // those values are currently used by @xstate/react directly so it's important to keep the assigned values in sync
478
- let ProcessingStatus = /*#__PURE__*/function (ProcessingStatus) {
479
- ProcessingStatus[ProcessingStatus["NotStarted"] = 0] = "NotStarted";
480
- ProcessingStatus[ProcessingStatus["Running"] = 1] = "Running";
481
- ProcessingStatus[ProcessingStatus["Stopped"] = 2] = "Stopped";
482
- return ProcessingStatus;
483
- }({});
484
- const defaultOptions = {
485
- clock: {
486
- setTimeout: (fn, ms) => {
487
- return setTimeout(fn, ms);
488
- },
489
- clearTimeout: id => {
490
- return clearTimeout(id);
491
- }
492
- },
493
- logger: console.log.bind(console),
494
- devTools: false
495
- };
496
-
497
- /**
498
- * An Actor is a running process that can receive events, send events and change
499
- * its behavior based on the events it receives, which can cause effects outside
500
- * of the actor. When you run a state machine, it becomes an actor.
501
- */
502
- class Actor {
503
- /**
504
- * Creates a new actor instance for the given logic with the provided options,
505
- * if any.
506
- *
507
- * @param logic The logic to create an actor from
508
- * @param options Actor options
509
- */
510
- constructor(logic, options) {
511
- this.logic = logic;
512
- /** The current internal state of the actor. */
513
- this._snapshot = void 0;
514
- /**
515
- * The clock that is responsible for setting and clearing timeouts, such as
516
- * delayed events and transitions.
517
- */
518
- this.clock = void 0;
519
- this.options = void 0;
520
- /** The unique identifier for this actor relative to its parent. */
521
- this.id = void 0;
522
- this.mailbox = new Mailbox(this._process.bind(this));
523
- this.observers = new Set();
524
- this.eventListeners = new Map();
525
- this.logger = void 0;
526
- /** @internal */
527
- this._processingStatus = ProcessingStatus.NotStarted;
528
- // Actor Ref
529
- this._parent = void 0;
530
- /** @internal */
531
- this._syncSnapshot = void 0;
532
- this.ref = void 0;
533
- // TODO: add typings for system
534
- this._actorScope = void 0;
535
- this.systemId = void 0;
536
- /** The globally unique process ID for this invocation. */
537
- this.sessionId = void 0;
538
- /** The system to which this actor belongs. */
539
- this.system = void 0;
540
- this._doneEvent = void 0;
541
- this.src = void 0;
542
- // array of functions to defer
543
- this._deferred = [];
544
- const resolvedOptions = {
545
- ...defaultOptions,
546
- ...options
547
- };
548
- const {
549
- clock,
550
- logger,
551
- parent,
552
- syncSnapshot,
553
- id,
554
- systemId,
555
- inspect
556
- } = resolvedOptions;
557
- this.system = parent ? parent.system : createSystem(this, {
558
- clock,
559
- logger
560
- });
561
- if (inspect && !parent) {
562
- // Always inspect at the system-level
563
- this.system.inspect(toObserver(inspect));
564
- }
565
- this.sessionId = this.system._bookId();
566
- this.id = id ?? this.sessionId;
567
- this.logger = options?.logger ?? this.system._logger;
568
- this.clock = options?.clock ?? this.system._clock;
569
- this._parent = parent;
570
- this._syncSnapshot = syncSnapshot;
571
- this.options = resolvedOptions;
572
- this.src = resolvedOptions.src ?? logic;
573
- this.ref = this;
574
- this._actorScope = {
575
- self: this,
576
- id: this.id,
577
- sessionId: this.sessionId,
578
- logger: this.logger,
579
- defer: fn => {
580
- this._deferred.push(fn);
581
- },
582
- system: this.system,
583
- stopChild: child => {
584
- if (child._parent !== this) {
585
- throw new Error(`Cannot stop child actor ${child.id} of ${this.id} because it is not a child`);
586
- }
587
- child._stop();
588
- },
589
- emit: emittedEvent => {
590
- const listeners = this.eventListeners.get(emittedEvent.type);
591
- const wildcardListener = this.eventListeners.get('*');
592
- if (!listeners && !wildcardListener) {
593
- return;
594
- }
595
- const allListeners = [...(listeners ? listeners.values() : []), ...(wildcardListener ? wildcardListener.values() : [])];
596
- for (const handler of allListeners) {
597
- try {
598
- handler(emittedEvent);
599
- } catch (err) {
600
- reportUnhandledError(err);
601
- }
602
- }
603
- },
604
- actionExecutor: action => {
605
- const exec = () => {
606
- this._actorScope.system._sendInspectionEvent({
607
- type: '@xstate.action',
608
- actorRef: this,
609
- action: {
610
- type: action.type,
611
- params: action.params
612
- }
613
- });
614
- if (!action.exec) {
615
- return;
616
- }
617
- const saveExecutingCustomAction = executingCustomAction;
618
- try {
619
- executingCustomAction = true;
620
- action.exec(action.info, action.params);
621
- } finally {
622
- executingCustomAction = saveExecutingCustomAction;
623
- }
624
- };
625
- if (this._processingStatus === ProcessingStatus.Running) {
626
- exec();
627
- } else {
628
- this._deferred.push(exec);
629
- }
630
- }
631
- };
632
-
633
- // Ensure that the send method is bound to this Actor instance
634
- // if destructured
635
- this.send = this.send.bind(this);
636
- this.system._sendInspectionEvent({
637
- type: '@xstate.actor',
638
- actorRef: this
639
- });
640
- if (systemId) {
641
- this.systemId = systemId;
642
- this.system._set(systemId, this);
643
- }
644
- this._initState(options?.snapshot ?? options?.state);
645
- if (systemId && this._snapshot.status !== 'active') {
646
- this.system._unregister(this);
647
- }
648
- }
649
- _initState(persistedState) {
650
- try {
651
- this._snapshot = persistedState ? this.logic.restoreSnapshot ? this.logic.restoreSnapshot(persistedState, this._actorScope) : persistedState : this.logic.getInitialSnapshot(this._actorScope, this.options?.input);
652
- } catch (err) {
653
- // if we get here then it means that we assign a value to this._snapshot that is not of the correct type
654
- // we can't get the true `TSnapshot & { status: 'error'; }`, it's impossible
655
- // so right now this is a lie of sorts
656
- this._snapshot = {
657
- status: 'error',
658
- output: undefined,
659
- error: err
660
- };
661
- }
662
- }
663
- update(snapshot, event) {
664
- // Update state
665
- this._snapshot = snapshot;
666
-
667
- // Execute deferred effects
668
- let deferredFn;
669
- while (deferredFn = this._deferred.shift()) {
670
- try {
671
- deferredFn();
672
- } catch (err) {
673
- // this error can only be caught when executing *initial* actions
674
- // it's the only time when we call actions provided by the user through those deferreds
675
- // when the actor is already running we always execute them synchronously while transitioning
676
- // no "builtin deferred" should actually throw an error since they are either safe
677
- // or the control flow is passed through the mailbox and errors should be caught by the `_process` used by the mailbox
678
- this._deferred.length = 0;
679
- this._snapshot = {
680
- ...snapshot,
681
- status: 'error',
682
- error: err
683
- };
684
- }
685
- }
686
- switch (this._snapshot.status) {
687
- case 'active':
688
- for (const observer of this.observers) {
689
- try {
690
- observer.next?.(snapshot);
691
- } catch (err) {
692
- reportUnhandledError(err);
693
- }
694
- }
695
- break;
696
- case 'done':
697
- // next observers are meant to be notified about done snapshots
698
- // this can be seen as something that is different from how observable work
699
- // but with observables `complete` callback is called without any arguments
700
- // it's more ergonomic for XState to treat a done snapshot as a "next" value
701
- // and the completion event as something that is separate,
702
- // something that merely follows emitting that done snapshot
703
- for (const observer of this.observers) {
704
- try {
705
- observer.next?.(snapshot);
706
- } catch (err) {
707
- reportUnhandledError(err);
708
- }
709
- }
710
- this._stopProcedure();
711
- this._complete();
712
- this._doneEvent = createDoneActorEvent(this.id, this._snapshot.output);
713
- if (this._parent) {
714
- this.system._relay(this, this._parent, this._doneEvent);
715
- }
716
- break;
717
- case 'error':
718
- this._error(this._snapshot.error);
719
- break;
720
- }
721
- this.system._sendInspectionEvent({
722
- type: '@xstate.snapshot',
723
- actorRef: this,
724
- event,
725
- snapshot
726
- });
727
- }
728
-
729
- /**
730
- * Subscribe an observer to an actor’s snapshot values.
731
- *
732
- * @remarks
733
- * The observer will receive the actor’s snapshot value when it is emitted.
734
- * The observer can be:
735
- *
736
- * - A plain function that receives the latest snapshot, or
737
- * - An observer object whose `.next(snapshot)` method receives the latest
738
- * snapshot
739
- *
740
- * @example
741
- *
742
- * ```ts
743
- * // Observer as a plain function
744
- * const subscription = actor.subscribe((snapshot) => {
745
- * console.log(snapshot);
746
- * });
747
- * ```
748
- *
749
- * @example
750
- *
751
- * ```ts
752
- * // Observer as an object
753
- * const subscription = actor.subscribe({
754
- * next(snapshot) {
755
- * console.log(snapshot);
756
- * },
757
- * error(err) {
758
- * // ...
759
- * },
760
- * complete() {
761
- * // ...
762
- * }
763
- * });
764
- * ```
765
- *
766
- * The return value of `actor.subscribe(observer)` is a subscription object
767
- * that has an `.unsubscribe()` method. You can call
768
- * `subscription.unsubscribe()` to unsubscribe the observer:
769
- *
770
- * @example
771
- *
772
- * ```ts
773
- * const subscription = actor.subscribe((snapshot) => {
774
- * // ...
775
- * });
776
- *
777
- * // Unsubscribe the observer
778
- * subscription.unsubscribe();
779
- * ```
780
- *
781
- * When the actor is stopped, all of its observers will automatically be
782
- * unsubscribed.
783
- *
784
- * @param observer - Either a plain function that receives the latest
785
- * snapshot, or an observer object whose `.next(snapshot)` method receives
786
- * the latest snapshot
787
- */
788
-
789
- subscribe(nextListenerOrObserver, errorListener, completeListener) {
790
- const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
791
- if (this._processingStatus !== ProcessingStatus.Stopped) {
792
- this.observers.add(observer);
793
- } else {
794
- switch (this._snapshot.status) {
795
- case 'done':
796
- try {
797
- observer.complete?.();
798
- } catch (err) {
799
- reportUnhandledError(err);
800
- }
801
- break;
802
- case 'error':
803
- {
804
- const err = this._snapshot.error;
805
- if (!observer.error) {
806
- reportUnhandledError(err);
807
- } else {
808
- try {
809
- observer.error(err);
810
- } catch (err) {
811
- reportUnhandledError(err);
812
- }
813
- }
814
- break;
815
- }
816
- }
817
- }
818
- return {
819
- unsubscribe: () => {
820
- this.observers.delete(observer);
821
- }
822
- };
823
- }
824
- on(type, handler) {
825
- let listeners = this.eventListeners.get(type);
826
- if (!listeners) {
827
- listeners = new Set();
828
- this.eventListeners.set(type, listeners);
829
- }
830
- const wrappedHandler = handler.bind(undefined);
831
- listeners.add(wrappedHandler);
832
- return {
833
- unsubscribe: () => {
834
- listeners.delete(wrappedHandler);
835
- }
836
- };
837
- }
838
- select(selector, equalityFn = Object.is) {
839
- return {
840
- subscribe: observerOrFn => {
841
- const observer = toObserver(observerOrFn);
842
- const snapshot = this.getSnapshot();
843
- let previousSelected = selector(snapshot);
844
- return this.subscribe(snapshot => {
845
- const nextSelected = selector(snapshot);
846
- if (!equalityFn(previousSelected, nextSelected)) {
847
- previousSelected = nextSelected;
848
- observer.next?.(nextSelected);
849
- }
850
- });
851
- },
852
- get: () => selector(this.getSnapshot())
853
- };
854
- }
855
-
856
- /** Starts the Actor from the initial state */
857
- start() {
858
- if (this._processingStatus === ProcessingStatus.Running) {
859
- // Do not restart the service if it is already started
860
- return this;
861
- }
862
- if (this._syncSnapshot) {
863
- this.subscribe({
864
- next: snapshot => {
865
- if (snapshot.status === 'active') {
866
- this.system._relay(this, this._parent, {
867
- type: `xstate.snapshot.${this.id}`,
868
- snapshot
869
- });
870
- }
871
- },
872
- error: () => {}
873
- });
874
- }
875
- this.system._register(this.sessionId, this);
876
- if (this.systemId) {
877
- this.system._set(this.systemId, this);
878
- }
879
- this._processingStatus = ProcessingStatus.Running;
880
-
881
- // TODO: this isn't correct when rehydrating
882
- const initEvent = createInitEvent(this.options.input);
883
- this.system._sendInspectionEvent({
884
- type: '@xstate.event',
885
- sourceRef: this._parent,
886
- actorRef: this,
887
- event: initEvent
888
- });
889
- const status = this._snapshot.status;
890
- switch (status) {
891
- case 'done':
892
- // a state machine can be "done" upon initialization (it could reach a final state using initial microsteps)
893
- // we still need to complete observers, flush deferreds etc
894
- this.update(this._snapshot, initEvent);
895
- // TODO: rethink cleanup of observers, mailbox, etc
896
- return this;
897
- case 'error':
898
- this._error(this._snapshot.error);
899
- return this;
900
- }
901
- if (!this._parent) {
902
- this.system.start();
903
- }
904
- if (this.logic.start) {
905
- try {
906
- this.logic.start(this._snapshot, this._actorScope);
907
- } catch (err) {
908
- this._snapshot = {
909
- ...this._snapshot,
910
- status: 'error',
911
- error: err
912
- };
913
- this._error(err);
914
- return this;
915
- }
916
- }
917
-
918
- // TODO: this notifies all subscribers but usually this is redundant
919
- // there is no real change happening here
920
- // we need to rethink if this needs to be refactored
921
- this.update(this._snapshot, initEvent);
922
- if (this.options.devTools) {
923
- this.attachDevTools();
924
- }
925
- this.mailbox.start();
926
- return this;
927
- }
928
- _process(event) {
929
- let nextState;
930
- let caughtError;
931
- try {
932
- nextState = this.logic.transition(this._snapshot, event, this._actorScope);
933
- } catch (err) {
934
- // we wrap it in a box so we can rethrow it later even if falsy value gets caught here
935
- caughtError = {
936
- err
937
- };
938
- }
939
- if (caughtError) {
940
- const {
941
- err
942
- } = caughtError;
943
- this._snapshot = {
944
- ...this._snapshot,
945
- status: 'error',
946
- error: err
947
- };
948
- this._error(err);
949
- return;
950
- }
951
- this.update(nextState, event);
952
- if (event.type === XSTATE_STOP) {
953
- this._stopProcedure();
954
- this._complete();
955
- }
956
- }
957
- _stop() {
958
- if (this._processingStatus === ProcessingStatus.Stopped) {
959
- return this;
960
- }
961
- this.mailbox.clear();
962
- if (this._processingStatus === ProcessingStatus.NotStarted) {
963
- this._processingStatus = ProcessingStatus.Stopped;
964
- return this;
965
- }
966
- this.mailbox.enqueue({
967
- type: XSTATE_STOP
968
- });
969
- return this;
970
- }
971
-
972
- /** Stops the Actor and unsubscribe all listeners. */
973
- stop() {
974
- if (this._parent) {
975
- throw new Error('A non-root actor cannot be stopped directly.');
976
- }
977
- return this._stop();
978
- }
979
- _complete() {
980
- for (const observer of this.observers) {
981
- try {
982
- observer.complete?.();
983
- } catch (err) {
984
- reportUnhandledError(err);
985
- }
986
- }
987
- this.observers.clear();
988
- this.eventListeners.clear();
989
- }
990
- _reportError(err) {
991
- if (!this.observers.size) {
992
- if (!this._parent) {
993
- reportUnhandledError(err);
994
- }
995
- this.eventListeners.clear();
996
- return;
997
- }
998
- let reportError = false;
999
- for (const observer of this.observers) {
1000
- const errorListener = observer.error;
1001
- reportError ||= !errorListener;
1002
- try {
1003
- errorListener?.(err);
1004
- } catch (err2) {
1005
- reportUnhandledError(err2);
1006
- }
1007
- }
1008
- this.observers.clear();
1009
- this.eventListeners.clear();
1010
- if (reportError) {
1011
- reportUnhandledError(err);
1012
- }
1013
- }
1014
- _error(err) {
1015
- this._stopProcedure();
1016
- this._reportError(err);
1017
- if (this._parent) {
1018
- this.system._relay(this, this._parent, createErrorActorEvent(this.id, err));
1019
- }
1020
- }
1021
- // TODO: atm children don't belong entirely to the actor so
1022
- // in a way - it's not even super aware of them
1023
- // so we can't stop them from here but we really should!
1024
- // right now, they are being stopped within the machine's transition
1025
- // but that could throw and leave us with "orphaned" active actors
1026
- _stopProcedure() {
1027
- if (this._processingStatus !== ProcessingStatus.Running) {
1028
- // Actor already stopped; do nothing
1029
- return this;
1030
- }
1031
-
1032
- // Cancel all delayed events
1033
- this.system.scheduler.cancelAll(this);
1034
-
1035
- // TODO: mailbox.reset
1036
- this.mailbox.clear();
1037
- // TODO: after `stop` we must prepare ourselves for receiving events again
1038
- // events sent *after* stop signal must be queued
1039
- // it seems like this should be the common behavior for all of our consumers
1040
- // so perhaps this should be unified somehow for all of them
1041
- this.mailbox = new Mailbox(this._process.bind(this));
1042
- this._processingStatus = ProcessingStatus.Stopped;
1043
- this.system._unregister(this);
1044
- return this;
1045
- }
1046
-
1047
- /** @internal */
1048
- _send(event) {
1049
- if (this._processingStatus === ProcessingStatus.Stopped) {
1050
- return;
1051
- }
1052
- this.mailbox.enqueue(event);
1053
- }
1054
-
1055
- /**
1056
- * Sends an event to the running Actor to trigger a transition.
1057
- *
1058
- * @param event The event to send
1059
- */
1060
- send(event) {
1061
- this.system._relay(undefined, this, event);
1062
- }
1063
- attachDevTools() {
1064
- const {
1065
- devTools
1066
- } = this.options;
1067
- if (devTools) {
1068
- const resolvedDevToolsAdapter = typeof devTools === 'function' ? devTools : dev_dist_xstateDev.devToolsAdapter;
1069
- resolvedDevToolsAdapter(this);
1070
- }
1071
- }
1072
- toJSON() {
1073
- return {
1074
- xstate$$type: $$ACTOR_TYPE,
1075
- id: this.id
1076
- };
1077
- }
1078
-
1079
- /**
1080
- * Obtain the internal state of the actor, which can be persisted.
1081
- *
1082
- * @remarks
1083
- * The internal state can be persisted from any actor, not only machines.
1084
- *
1085
- * Note that the persisted state is not the same as the snapshot from
1086
- * {@link Actor.getSnapshot}. Persisted state represents the internal state of
1087
- * the actor, while snapshots represent the actor's last emitted value.
1088
- *
1089
- * Can be restored with {@link ActorOptions.state}
1090
- * @see https://stately.ai/docs/persistence
1091
- */
1092
-
1093
- getPersistedSnapshot(options) {
1094
- return this.logic.getPersistedSnapshot(this._snapshot, options);
1095
- }
1096
- [symbolObservable]() {
1097
- return this;
1098
- }
1099
-
1100
- /**
1101
- * Read an actor’s snapshot synchronously.
1102
- *
1103
- * @remarks
1104
- * The snapshot represent an actor's last emitted value.
1105
- *
1106
- * When an actor receives an event, its internal state may change. An actor
1107
- * may emit a snapshot when a state transition occurs.
1108
- *
1109
- * Note that some actors, such as callback actors generated with
1110
- * `fromCallback`, will not emit snapshots.
1111
- * @see {@link Actor.subscribe} to subscribe to an actor’s snapshot values.
1112
- * @see {@link Actor.getPersistedSnapshot} to persist the internal state of an actor (which is more than just a snapshot).
1113
- */
1114
- getSnapshot() {
1115
- return this._snapshot;
1116
- }
1117
- }
1118
- /**
1119
- * Creates a new actor instance for the given actor logic with the provided
1120
- * options, if any.
1121
- *
1122
- * @remarks
1123
- * When you create an actor from actor logic via `createActor(logic)`, you
1124
- * implicitly create an actor system where the created actor is the root actor.
1125
- * Any actors spawned from this root actor and its descendants are part of that
1126
- * actor system.
1127
- * @example
1128
- *
1129
- * ```ts
1130
- * import { createActor } from 'xstate';
1131
- * import { someActorLogic } from './someActorLogic.ts';
1132
- *
1133
- * // Creating the actor, which implicitly creates an actor system with itself as the root actor
1134
- * const actor = createActor(someActorLogic);
1135
- *
1136
- * actor.subscribe((snapshot) => {
1137
- * console.log(snapshot);
1138
- * });
1139
- *
1140
- * // Actors must be started by calling `actor.start()`, which will also start the actor system.
1141
- * actor.start();
1142
- *
1143
- * // Actors can receive events
1144
- * actor.send({ type: 'someEvent' });
1145
- *
1146
- * // You can stop root actors by calling `actor.stop()`, which will also stop the actor system and all actors in that system.
1147
- * actor.stop();
1148
- * ```
1149
- *
1150
- * @param logic - The actor logic to create an actor from. For a state machine
1151
- * actor logic creator, see {@link createMachine}. Other actor logic creators
1152
- * include {@link fromCallback}, {@link fromEventObservable},
1153
- * {@link fromObservable}, {@link fromPromise}, and {@link fromTransition}.
1154
- * @param options - Actor options
1155
- */
1156
- function createActor(logic, ...[options]) {
1157
- return new Actor(logic, options);
1158
- }
1159
-
1160
- /**
1161
- * Creates a new Interpreter instance for the given machine with the provided
1162
- * options, if any.
1163
- *
1164
- * @deprecated Use `createActor` instead
1165
- * @alias
1166
- */
1167
- const interpret = createActor;
1168
-
1169
- /**
1170
- * @deprecated Use `Actor` instead.
1171
- * @alias
1172
- */
1173
-
1174
- function resolveCancel(_, snapshot, actionArgs, actionParams, {
1175
- sendId
1176
- }) {
1177
- const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs, actionParams) : sendId;
1178
- return [snapshot, {
1179
- sendId: resolvedSendId
1180
- }, undefined];
1181
- }
1182
- function executeCancel(actorScope, params) {
1183
- actorScope.defer(() => {
1184
- actorScope.system.scheduler.cancel(actorScope.self, params.sendId);
1185
- });
1186
- }
1187
- /**
1188
- * Cancels a delayed `sendTo(...)` action that is waiting to be executed. The
1189
- * canceled `sendTo(...)` action will not send its event or execute, unless the
1190
- * `delay` has already elapsed before `cancel(...)` is called.
1191
- *
1192
- * @example
1193
- *
1194
- * ```ts
1195
- * import { createMachine, sendTo, cancel } from 'xstate';
1196
- *
1197
- * const machine = createMachine({
1198
- * // ...
1199
- * on: {
1200
- * sendEvent: {
1201
- * actions: sendTo(
1202
- * 'some-actor',
1203
- * { type: 'someEvent' },
1204
- * {
1205
- * id: 'some-id',
1206
- * delay: 1000
1207
- * }
1208
- * )
1209
- * },
1210
- * cancelEvent: {
1211
- * actions: cancel('some-id')
1212
- * }
1213
- * }
1214
- * });
1215
- * ```
1216
- *
1217
- * @param sendId The `id` of the `sendTo(...)` action to cancel.
1218
- */
1219
- function cancel(sendId) {
1220
- function cancel(_args, _params) {
1221
- }
1222
- cancel.type = 'xstate.cancel';
1223
- cancel.sendId = sendId;
1224
- cancel.resolve = resolveCancel;
1225
- cancel.execute = executeCancel;
1226
- return cancel;
1227
- }
1228
-
1229
- function resolveSpawn(actorScope, snapshot, actionArgs, _actionParams, {
1230
- id,
1231
- systemId,
1232
- src,
1233
- input,
1234
- syncSnapshot
1235
- }) {
1236
- const logic = typeof src === 'string' ? resolveReferencedActor(snapshot.machine, src) : src;
1237
- const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
1238
- let actorRef;
1239
- let resolvedInput = undefined;
1240
- if (logic) {
1241
- resolvedInput = typeof input === 'function' ? input({
1242
- context: snapshot.context,
1243
- event: actionArgs.event,
1244
- self: actorScope.self
1245
- }) : input;
1246
- actorRef = createActor(logic, {
1247
- id: resolvedId,
1248
- src,
1249
- parent: actorScope.self,
1250
- syncSnapshot,
1251
- systemId,
1252
- input: resolvedInput
1253
- });
1254
- }
1255
- return [cloneMachineSnapshot(snapshot, {
1256
- children: {
1257
- ...snapshot.children,
1258
- [resolvedId]: actorRef
1259
- }
1260
- }), {
1261
- id,
1262
- systemId,
1263
- actorRef,
1264
- src,
1265
- input: resolvedInput
1266
- }, undefined];
1267
- }
1268
- function executeSpawn(actorScope, {
1269
- actorRef
1270
- }) {
1271
- if (!actorRef) {
1272
- return;
1273
- }
1274
- actorScope.defer(() => {
1275
- if (actorRef._processingStatus === ProcessingStatus.Stopped) {
1276
- return;
1277
- }
1278
- actorRef.start();
1279
- });
1280
- }
1281
- function spawnChild(...[src, {
1282
- id,
1283
- systemId,
1284
- input,
1285
- syncSnapshot = false
1286
- } = {}]) {
1287
- function spawnChild(_args, _params) {
1288
- }
1289
- spawnChild.type = 'xstate.spawnChild';
1290
- spawnChild.id = id;
1291
- spawnChild.systemId = systemId;
1292
- spawnChild.src = src;
1293
- spawnChild.input = input;
1294
- spawnChild.syncSnapshot = syncSnapshot;
1295
- spawnChild.resolve = resolveSpawn;
1296
- spawnChild.execute = executeSpawn;
1297
- return spawnChild;
1298
- }
1299
-
1300
- function resolveStop(_, snapshot, args, actionParams, {
1301
- actorRef
1302
- }) {
1303
- const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
1304
- const resolvedActorRef = typeof actorRefOrString === 'string' ? snapshot.children[actorRefOrString] : actorRefOrString;
1305
- let children = snapshot.children;
1306
- if (resolvedActorRef) {
1307
- children = {
1308
- ...children
1309
- };
1310
- delete children[resolvedActorRef.id];
1311
- }
1312
- return [cloneMachineSnapshot(snapshot, {
1313
- children
1314
- }), resolvedActorRef, undefined];
1315
- }
1316
- function unregisterRecursively(actorScope, actorRef) {
1317
- // unregister children first (depth-first)
1318
- const snapshot = actorRef.getSnapshot();
1319
- if (snapshot && 'children' in snapshot) {
1320
- for (const child of Object.values(snapshot.children)) {
1321
- unregisterRecursively(actorScope, child);
1322
- }
1323
- }
1324
- actorScope.system._unregister(actorRef);
1325
- }
1326
- function executeStop(actorScope, actorRef) {
1327
- if (!actorRef) {
1328
- return;
1329
- }
1330
-
1331
- // we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
1332
- // since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
1333
- // this could throw on `systemId` collision, for example, when dealing with reentering transitions
1334
- // we also need to recursively unregister all nested children's systemIds
1335
- unregisterRecursively(actorScope, actorRef);
1336
-
1337
- // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
1338
- // this can happen, for example, when the invoking state is being exited immediately by an always transition
1339
- if (actorRef._processingStatus !== ProcessingStatus.Running) {
1340
- actorScope.stopChild(actorRef);
1341
- return;
1342
- }
1343
- // stopping a child enqueues a stop event in the child actor's mailbox
1344
- // we need for all of the already enqueued events to be processed before we stop the child
1345
- // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
1346
- // and we don't want to ignore those events
1347
- actorScope.defer(() => {
1348
- actorScope.stopChild(actorRef);
1349
- });
1350
- }
1351
- /**
1352
- * Stops a child actor.
1353
- *
1354
- * @param actorRef The actor to stop.
1355
- */
1356
- function stopChild(actorRef) {
1357
- function stop(_args, _params) {
1358
- }
1359
- stop.type = 'xstate.stopChild';
1360
- stop.actorRef = actorRef;
1361
- stop.resolve = resolveStop;
1362
- stop.execute = executeStop;
1363
- return stop;
1364
- }
1365
-
1366
- /**
1367
- * Stops a child actor.
1368
- *
1369
- * @deprecated Use `stopChild(...)` instead
1370
- * @alias
1371
- */
1372
- const stop = stopChild;
1373
-
1374
- function checkStateIn(snapshot, _, {
1375
- stateValue
1376
- }) {
1377
- if (typeof stateValue === 'string' && isStateId(stateValue)) {
1378
- const target = snapshot.machine.getStateNodeById(stateValue);
1379
- return snapshot._nodes.some(sn => sn === target);
1380
- }
1381
- return snapshot.matches(stateValue);
1382
- }
1383
- function stateIn(stateValue) {
1384
- function stateIn() {
1385
- return false;
1386
- }
1387
- stateIn.check = checkStateIn;
1388
- stateIn.stateValue = stateValue;
1389
- return stateIn;
1390
- }
1391
- function checkNot(snapshot, {
1392
- context,
1393
- event
1394
- }, {
1395
- guards
1396
- }) {
1397
- return !evaluateGuard(guards[0], context, event, snapshot);
1398
- }
1399
-
1400
- /**
1401
- * Higher-order guard that evaluates to `true` if the `guard` passed to it
1402
- * evaluates to `false`.
1403
- *
1404
- * @category Guards
1405
- * @example
1406
- *
1407
- * ```ts
1408
- * import { setup, not } from 'xstate';
1409
- *
1410
- * const machine = setup({
1411
- * guards: {
1412
- * someNamedGuard: () => false
1413
- * }
1414
- * }).createMachine({
1415
- * on: {
1416
- * someEvent: {
1417
- * guard: not('someNamedGuard'),
1418
- * actions: () => {
1419
- * // will be executed if guard in `not(...)`
1420
- * // evaluates to `false`
1421
- * }
1422
- * }
1423
- * }
1424
- * });
1425
- * ```
1426
- *
1427
- * @returns A guard
1428
- */
1429
- function not(guard) {
1430
- function not(_args, _params) {
1431
- return false;
1432
- }
1433
- not.check = checkNot;
1434
- not.guards = [guard];
1435
- return not;
1436
- }
1437
- function checkAnd(snapshot, {
1438
- context,
1439
- event
1440
- }, {
1441
- guards
1442
- }) {
1443
- return guards.every(guard => evaluateGuard(guard, context, event, snapshot));
1444
- }
1445
-
1446
- /**
1447
- * Higher-order guard that evaluates to `true` if all `guards` passed to it
1448
- * evaluate to `true`.
1449
- *
1450
- * @category Guards
1451
- * @example
1452
- *
1453
- * ```ts
1454
- * import { setup, and } from 'xstate';
1455
- *
1456
- * const machine = setup({
1457
- * guards: {
1458
- * someNamedGuard: () => true
1459
- * }
1460
- * }).createMachine({
1461
- * on: {
1462
- * someEvent: {
1463
- * guard: and([({ context }) => context.value > 0, 'someNamedGuard']),
1464
- * actions: () => {
1465
- * // will be executed if all guards in `and(...)`
1466
- * // evaluate to true
1467
- * }
1468
- * }
1469
- * }
1470
- * });
1471
- * ```
1472
- *
1473
- * @returns A guard action object
1474
- */
1475
- function and(guards) {
1476
- function and(_args, _params) {
1477
- return false;
1478
- }
1479
- and.check = checkAnd;
1480
- and.guards = guards;
1481
- return and;
1482
- }
1483
- function checkOr(snapshot, {
1484
- context,
1485
- event
1486
- }, {
1487
- guards
1488
- }) {
1489
- return guards.some(guard => evaluateGuard(guard, context, event, snapshot));
1490
- }
1491
-
1492
- /**
1493
- * Higher-order guard that evaluates to `true` if any of the `guards` passed to
1494
- * it evaluate to `true`.
1495
- *
1496
- * @category Guards
1497
- * @example
1498
- *
1499
- * ```ts
1500
- * import { setup, or } from 'xstate';
1501
- *
1502
- * const machine = setup({
1503
- * guards: {
1504
- * someNamedGuard: () => true
1505
- * }
1506
- * }).createMachine({
1507
- * on: {
1508
- * someEvent: {
1509
- * guard: or([({ context }) => context.value > 0, 'someNamedGuard']),
1510
- * actions: () => {
1511
- * // will be executed if any of the guards in `or(...)`
1512
- * // evaluate to true
1513
- * }
1514
- * }
1515
- * }
1516
- * });
1517
- * ```
1518
- *
1519
- * @returns A guard action object
1520
- */
1521
- function or(guards) {
1522
- function or(_args, _params) {
1523
- return false;
1524
- }
1525
- or.check = checkOr;
1526
- or.guards = guards;
1527
- return or;
1528
- }
1529
-
1530
- // TODO: throw on cycles (depth check should be enough)
1531
- function evaluateGuard(guard, context, event, snapshot) {
1532
- const {
1533
- machine
1534
- } = snapshot;
1535
- const isInline = typeof guard === 'function';
1536
- const resolved = isInline ? guard : machine.implementations.guards[typeof guard === 'string' ? guard : guard.type];
1537
- if (!isInline && !resolved) {
1538
- throw new Error(`Guard '${typeof guard === 'string' ? guard : guard.type}' is not implemented.'.`);
1539
- }
1540
- if (typeof resolved !== 'function') {
1541
- return evaluateGuard(resolved, context, event, snapshot);
1542
- }
1543
- const guardArgs = {
1544
- context,
1545
- event
1546
- };
1547
- const guardParams = isInline || typeof guard === 'string' ? undefined : 'params' in guard ? typeof guard.params === 'function' ? guard.params({
1548
- context,
1549
- event
1550
- }) : guard.params : undefined;
1551
- if (!('check' in resolved)) {
1552
- // the existing type of `.guards` assumes non-nullable `TExpressionGuard`
1553
- // inline guards expect `TExpressionGuard` to be set to `undefined`
1554
- // it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
1555
- return resolved(guardArgs, guardParams);
1556
- }
1557
- const builtinGuard = resolved;
1558
- return builtinGuard.check(snapshot, guardArgs, resolved // this holds all params
1559
- );
1560
- }
1561
-
1562
- function isAtomicStateNode(stateNode) {
1563
- return stateNode.type === 'atomic' || stateNode.type === 'final';
1564
- }
1565
- function getChildren(stateNode) {
1566
- return Object.values(stateNode.states).filter(sn => sn.type !== 'history');
1567
- }
1568
- function getProperAncestors(stateNode, toStateNode) {
1569
- const ancestors = [];
1570
- if (toStateNode === stateNode) {
1571
- return ancestors;
1572
- }
1573
-
1574
- // add all ancestors
1575
- let m = stateNode.parent;
1576
- while (m && m !== toStateNode) {
1577
- ancestors.push(m);
1578
- m = m.parent;
1579
- }
1580
- return ancestors;
1581
- }
1582
- function getAllStateNodes(stateNodes) {
1583
- const nodeSet = new Set(stateNodes);
1584
- const adjList = getAdjList(nodeSet);
1585
-
1586
- // add descendants
1587
- for (const s of nodeSet) {
1588
- // if previously active, add existing child nodes
1589
- if (s.type === 'compound' && (!adjList.get(s) || !adjList.get(s).length)) {
1590
- getInitialStateNodesWithTheirAncestors(s).forEach(sn => nodeSet.add(sn));
1591
- } else {
1592
- if (s.type === 'parallel') {
1593
- for (const child of getChildren(s)) {
1594
- if (child.type === 'history') {
1595
- continue;
1596
- }
1597
- if (!nodeSet.has(child)) {
1598
- const initialStates = getInitialStateNodesWithTheirAncestors(child);
1599
- for (const initialStateNode of initialStates) {
1600
- nodeSet.add(initialStateNode);
1601
- }
1602
- }
1603
- }
1604
- }
1605
- }
1606
- }
1607
-
1608
- // add all ancestors
1609
- for (const s of nodeSet) {
1610
- let m = s.parent;
1611
- while (m) {
1612
- nodeSet.add(m);
1613
- m = m.parent;
1614
- }
1615
- }
1616
- return nodeSet;
1617
- }
1618
- function getValueFromAdj(baseNode, adjList) {
1619
- const childStateNodes = adjList.get(baseNode);
1620
- if (!childStateNodes) {
1621
- return {}; // todo: fix?
1622
- }
1623
- if (baseNode.type === 'compound') {
1624
- const childStateNode = childStateNodes[0];
1625
- if (childStateNode) {
1626
- if (isAtomicStateNode(childStateNode)) {
1627
- return childStateNode.key;
1628
- }
1629
- } else {
1630
- return {};
1631
- }
1632
- }
1633
- const stateValue = {};
1634
- for (const childStateNode of childStateNodes) {
1635
- stateValue[childStateNode.key] = getValueFromAdj(childStateNode, adjList);
1636
- }
1637
- return stateValue;
1638
- }
1639
- function getAdjList(stateNodes) {
1640
- const adjList = new Map();
1641
- for (const s of stateNodes) {
1642
- if (!adjList.has(s)) {
1643
- adjList.set(s, []);
1644
- }
1645
- if (s.parent) {
1646
- if (!adjList.has(s.parent)) {
1647
- adjList.set(s.parent, []);
1648
- }
1649
- adjList.get(s.parent).push(s);
1650
- }
1651
- }
1652
- return adjList;
1653
- }
1654
- function getStateValue(rootNode, stateNodes) {
1655
- const config = getAllStateNodes(stateNodes);
1656
- return getValueFromAdj(rootNode, getAdjList(config));
1657
- }
1658
- function isInFinalState(stateNodeSet, stateNode) {
1659
- if (stateNode.type === 'compound') {
1660
- return getChildren(stateNode).some(s => s.type === 'final' && stateNodeSet.has(s));
1661
- }
1662
- if (stateNode.type === 'parallel') {
1663
- return getChildren(stateNode).every(sn => isInFinalState(stateNodeSet, sn));
1664
- }
1665
- return stateNode.type === 'final';
1666
- }
1667
- const isStateId = str => str[0] === STATE_IDENTIFIER;
1668
- function getCandidates(stateNode, receivedEventType) {
1669
- const candidates = stateNode.transitions.get(receivedEventType) || [...stateNode.transitions.keys()].filter(eventDescriptor => matchesEventDescriptor(receivedEventType, eventDescriptor)).sort((a, b) => b.length - a.length).flatMap(key => stateNode.transitions.get(key));
1670
- return candidates;
1671
- }
1672
-
1673
- /** All delayed transitions from the config. */
1674
- function getDelayedTransitions(stateNode) {
1675
- const afterConfig = stateNode.config.after;
1676
- if (!afterConfig) {
1677
- return [];
1678
- }
1679
- const mutateEntryExit = delay => {
1680
- const afterEvent = createAfterEvent(delay, stateNode.id);
1681
- const eventType = afterEvent.type;
1682
- stateNode.entry.push(raise(afterEvent, {
1683
- id: eventType,
1684
- delay
1685
- }));
1686
- stateNode.exit.push(cancel(eventType));
1687
- return eventType;
1688
- };
1689
- const delayedTransitions = Object.keys(afterConfig).flatMap(delay => {
1690
- const configTransition = afterConfig[delay];
1691
- const resolvedTransition = typeof configTransition === 'string' ? {
1692
- target: configTransition
1693
- } : configTransition;
1694
- const resolvedDelay = Number.isNaN(+delay) ? delay : +delay;
1695
- const eventType = mutateEntryExit(resolvedDelay);
1696
- return toArray(resolvedTransition).map(transition => ({
1697
- ...transition,
1698
- event: eventType,
1699
- delay: resolvedDelay
1700
- }));
1701
- });
1702
- return delayedTransitions.map(delayedTransition => {
1703
- const {
1704
- delay
1705
- } = delayedTransition;
1706
- return {
1707
- ...formatTransition(stateNode, delayedTransition.event, delayedTransition),
1708
- delay
1709
- };
1710
- });
1711
- }
1712
- function formatTransition(stateNode, descriptor, transitionConfig) {
1713
- const normalizedTarget = normalizeTarget(transitionConfig.target);
1714
- const reenter = transitionConfig.reenter ?? false;
1715
- const target = resolveTarget(stateNode, normalizedTarget);
1716
- const transition = {
1717
- ...transitionConfig,
1718
- actions: toArray(transitionConfig.actions),
1719
- guard: transitionConfig.guard,
1720
- target,
1721
- source: stateNode,
1722
- reenter,
1723
- eventType: descriptor,
1724
- toJSON: () => ({
1725
- ...transition,
1726
- source: `#${stateNode.id}`,
1727
- target: target ? target.map(t => `#${t.id}`) : undefined
1728
- })
1729
- };
1730
- return transition;
1731
- }
1732
- function formatTransitions(stateNode) {
1733
- const transitions = new Map();
1734
- if (stateNode.config.on) {
1735
- for (const descriptor of Object.keys(stateNode.config.on)) {
1736
- if (descriptor === NULL_EVENT) {
1737
- throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');
1738
- }
1739
- const transitionsConfig = stateNode.config.on[descriptor];
1740
- transitions.set(descriptor, toTransitionConfigArray(transitionsConfig).map(t => formatTransition(stateNode, descriptor, t)));
1741
- }
1742
- }
1743
- if (stateNode.config.onDone) {
1744
- const descriptor = `xstate.done.state.${stateNode.id}`;
1745
- transitions.set(descriptor, toTransitionConfigArray(stateNode.config.onDone).map(t => formatTransition(stateNode, descriptor, t)));
1746
- }
1747
- for (const invokeDef of stateNode.invoke) {
1748
- if (invokeDef.onDone) {
1749
- const descriptor = `xstate.done.actor.${invokeDef.id}`;
1750
- transitions.set(descriptor, toTransitionConfigArray(invokeDef.onDone).map(t => formatTransition(stateNode, descriptor, t)));
1751
- }
1752
- if (invokeDef.onError) {
1753
- const descriptor = `xstate.error.actor.${invokeDef.id}`;
1754
- transitions.set(descriptor, toTransitionConfigArray(invokeDef.onError).map(t => formatTransition(stateNode, descriptor, t)));
1755
- }
1756
- if (invokeDef.onSnapshot) {
1757
- const descriptor = `xstate.snapshot.${invokeDef.id}`;
1758
- transitions.set(descriptor, toTransitionConfigArray(invokeDef.onSnapshot).map(t => formatTransition(stateNode, descriptor, t)));
1759
- }
1760
- }
1761
- for (const delayedTransition of stateNode.after) {
1762
- let existing = transitions.get(delayedTransition.eventType);
1763
- if (!existing) {
1764
- existing = [];
1765
- transitions.set(delayedTransition.eventType, existing);
1766
- }
1767
- existing.push(delayedTransition);
1768
- }
1769
- return transitions;
1770
- }
1771
-
1772
- /**
1773
- * Collects route transitions from all descendants with explicit IDs. Called
1774
- * once on the root node to avoid O(N²) repeated traversals.
1775
- */
1776
- function formatRouteTransitions(rootStateNode) {
1777
- const routeTransitions = [];
1778
- const collectRoutes = states => {
1779
- Object.values(states).forEach(sn => {
1780
- if (sn.config.route && sn.config.id) {
1781
- const routeId = sn.config.id;
1782
- const userGuard = sn.config.route.guard;
1783
- const routeGuard = (args, params) => {
1784
- if (args.event.to !== `#${routeId}`) {
1785
- return false;
1786
- }
1787
- if (!userGuard) {
1788
- return true;
1789
- }
1790
- if (typeof userGuard === 'function') {
1791
- return userGuard(args, params);
1792
- }
1793
- return true;
1794
- };
1795
- const transition = {
1796
- ...sn.config.route,
1797
- guard: routeGuard,
1798
- target: `#${routeId}`
1799
- };
1800
- routeTransitions.push(formatTransition(rootStateNode, 'xstate.route', transition));
1801
- }
1802
- if (sn.states) {
1803
- collectRoutes(sn.states);
1804
- }
1805
- });
1806
- };
1807
- collectRoutes(rootStateNode.states);
1808
- if (routeTransitions.length > 0) {
1809
- rootStateNode.transitions.set('xstate.route', routeTransitions);
1810
- }
1811
- }
1812
- function formatInitialTransition(stateNode, _target) {
1813
- const resolvedTarget = typeof _target === 'string' ? stateNode.states[_target] : _target ? stateNode.states[_target.target] : undefined;
1814
- if (!resolvedTarget && _target) {
1815
- throw new Error(
1816
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-base-to-string
1817
- `Initial state node "${_target}" not found on parent state node #${stateNode.id}`);
1818
- }
1819
- const transition = {
1820
- source: stateNode,
1821
- actions: !_target || typeof _target === 'string' ? [] : toArray(_target.actions),
1822
- eventType: null,
1823
- reenter: false,
1824
- target: resolvedTarget ? [resolvedTarget] : [],
1825
- toJSON: () => ({
1826
- ...transition,
1827
- source: `#${stateNode.id}`,
1828
- target: resolvedTarget ? [`#${resolvedTarget.id}`] : []
1829
- })
1830
- };
1831
- return transition;
1832
- }
1833
- function resolveTarget(stateNode, targets) {
1834
- if (targets === undefined) {
1835
- // an undefined target signals that the state node should not transition from that state when receiving that event
1836
- return undefined;
1837
- }
1838
- return targets.map(target => {
1839
- if (typeof target !== 'string') {
1840
- return target;
1841
- }
1842
- if (isStateId(target)) {
1843
- return stateNode.machine.getStateNodeById(target);
1844
- }
1845
- const isInternalTarget = target[0] === STATE_DELIMITER;
1846
- // If internal target is defined on machine,
1847
- // do not include machine key on target
1848
- if (isInternalTarget && !stateNode.parent) {
1849
- return getStateNodeByPath(stateNode, target.slice(1));
1850
- }
1851
- const resolvedTarget = isInternalTarget ? stateNode.key + target : target;
1852
- if (stateNode.parent) {
1853
- try {
1854
- const targetStateNode = getStateNodeByPath(stateNode.parent, resolvedTarget);
1855
- return targetStateNode;
1856
- } catch (err) {
1857
- throw new Error(`Invalid transition definition for state node '${stateNode.id}':\n${err.message}`);
1858
- }
1859
- } else {
1860
- throw new Error(`Invalid target: "${target}" is not a valid target from the root node. Did you mean ".${target}"?`);
1861
- }
1862
- });
1863
- }
1864
- function resolveHistoryDefaultTransition(stateNode) {
1865
- const normalizedTarget = normalizeTarget(stateNode.config.target);
1866
- if (!normalizedTarget) {
1867
- return stateNode.parent.initial;
1868
- }
1869
- return {
1870
- target: normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t)
1871
- };
1872
- }
1873
- function isHistoryNode(stateNode) {
1874
- return stateNode.type === 'history';
1875
- }
1876
- function getInitialStateNodesWithTheirAncestors(stateNode) {
1877
- const states = getInitialStateNodes(stateNode);
1878
- for (const initialState of states) {
1879
- for (const ancestor of getProperAncestors(initialState, stateNode)) {
1880
- states.add(ancestor);
1881
- }
1882
- }
1883
- return states;
1884
- }
1885
- function getInitialStateNodes(stateNode) {
1886
- const set = new Set();
1887
- function iter(descStateNode) {
1888
- if (set.has(descStateNode)) {
1889
- return;
1890
- }
1891
- set.add(descStateNode);
1892
- if (descStateNode.type === 'compound') {
1893
- iter(descStateNode.initial.target[0]);
1894
- } else if (descStateNode.type === 'parallel') {
1895
- for (const child of getChildren(descStateNode)) {
1896
- iter(child);
1897
- }
1898
- }
1899
- }
1900
- iter(stateNode);
1901
- return set;
1902
- }
1903
- /** Returns the child state node from its relative `stateKey`, or throws. */
1904
- function getStateNode(stateNode, stateKey) {
1905
- if (isStateId(stateKey)) {
1906
- return stateNode.machine.getStateNodeById(stateKey);
1907
- }
1908
- if (!stateNode.states) {
1909
- throw new Error(`Unable to retrieve child state '${stateKey}' from '${stateNode.id}'; no child states exist.`);
1910
- }
1911
- const result = stateNode.states[stateKey];
1912
- if (!result) {
1913
- throw new Error(`Child state '${stateKey}' does not exist on '${stateNode.id}'`);
1914
- }
1915
- return result;
1916
- }
1917
-
1918
- /**
1919
- * Returns the relative state node from the given `statePath`, or throws.
1920
- *
1921
- * @param statePath The string or string array relative path to the state node.
1922
- */
1923
- function getStateNodeByPath(stateNode, statePath) {
1924
- if (typeof statePath === 'string' && isStateId(statePath)) {
1925
- try {
1926
- return stateNode.machine.getStateNodeById(statePath);
1927
- } catch {
1928
- // try individual paths
1929
- // throw e;
1930
- }
1931
- }
1932
- const arrayStatePath = toStatePath(statePath).slice();
1933
- let currentStateNode = stateNode;
1934
- while (arrayStatePath.length) {
1935
- const key = arrayStatePath.shift();
1936
- if (!key.length) {
1937
- break;
1938
- }
1939
- currentStateNode = getStateNode(currentStateNode, key);
1940
- }
1941
- return currentStateNode;
1942
- }
1943
-
1944
- /**
1945
- * Returns the state nodes represented by the current state value.
1946
- *
1947
- * @param stateValue The state value or State instance
1948
- */
1949
- function getStateNodes(stateNode, stateValue) {
1950
- if (typeof stateValue === 'string') {
1951
- const childStateNode = stateNode.states[stateValue];
1952
- if (!childStateNode) {
1953
- throw new Error(`State '${stateValue}' does not exist on '${stateNode.id}'`);
1954
- }
1955
- return [stateNode, childStateNode];
1956
- }
1957
- const childStateKeys = Object.keys(stateValue);
1958
- const childStateNodes = childStateKeys.map(subStateKey => getStateNode(stateNode, subStateKey)).filter(Boolean);
1959
- return [stateNode.machine.root, stateNode].concat(childStateNodes, childStateKeys.reduce((allSubStateNodes, subStateKey) => {
1960
- const subStateNode = getStateNode(stateNode, subStateKey);
1961
- if (!subStateNode) {
1962
- return allSubStateNodes;
1963
- }
1964
- const subStateNodes = getStateNodes(subStateNode, stateValue[subStateKey]);
1965
- return allSubStateNodes.concat(subStateNodes);
1966
- }, []));
1967
- }
1968
- function transitionAtomicNode(stateNode, stateValue, snapshot, event) {
1969
- const childStateNode = getStateNode(stateNode, stateValue);
1970
- const next = childStateNode.next(snapshot, event);
1971
- if (!next || !next.length) {
1972
- return stateNode.next(snapshot, event);
1973
- }
1974
- return next;
1975
- }
1976
- function transitionCompoundNode(stateNode, stateValue, snapshot, event) {
1977
- const subStateKeys = Object.keys(stateValue);
1978
- const childStateNode = getStateNode(stateNode, subStateKeys[0]);
1979
- const next = transitionNode(childStateNode, stateValue[subStateKeys[0]], snapshot, event);
1980
- if (!next || !next.length) {
1981
- return stateNode.next(snapshot, event);
1982
- }
1983
- return next;
1984
- }
1985
- function transitionParallelNode(stateNode, stateValue, snapshot, event) {
1986
- const allInnerTransitions = [];
1987
- for (const subStateKey of Object.keys(stateValue)) {
1988
- const subStateValue = stateValue[subStateKey];
1989
- if (!subStateValue) {
1990
- continue;
1991
- }
1992
- const subStateNode = getStateNode(stateNode, subStateKey);
1993
- const innerTransitions = transitionNode(subStateNode, subStateValue, snapshot, event);
1994
- if (innerTransitions) {
1995
- allInnerTransitions.push(...innerTransitions);
1996
- }
1997
- }
1998
- if (!allInnerTransitions.length) {
1999
- return stateNode.next(snapshot, event);
2000
- }
2001
- return allInnerTransitions;
2002
- }
2003
- function transitionNode(stateNode, stateValue, snapshot, event) {
2004
- // leaf node
2005
- if (typeof stateValue === 'string') {
2006
- return transitionAtomicNode(stateNode, stateValue, snapshot, event);
2007
- }
2008
-
2009
- // compound node
2010
- if (Object.keys(stateValue).length === 1) {
2011
- return transitionCompoundNode(stateNode, stateValue, snapshot, event);
2012
- }
2013
-
2014
- // parallel node
2015
- return transitionParallelNode(stateNode, stateValue, snapshot, event);
2016
- }
2017
- function getHistoryNodes(stateNode) {
2018
- return Object.keys(stateNode.states).map(key => stateNode.states[key]).filter(sn => sn.type === 'history');
2019
- }
2020
- function isDescendant(childStateNode, parentStateNode) {
2021
- let marker = childStateNode;
2022
- while (marker.parent && marker.parent !== parentStateNode) {
2023
- marker = marker.parent;
2024
- }
2025
- return marker.parent === parentStateNode;
2026
- }
2027
- function hasIntersection(s1, s2) {
2028
- const set1 = new Set(s1);
2029
- const set2 = new Set(s2);
2030
- for (const item of set1) {
2031
- if (set2.has(item)) {
2032
- return true;
2033
- }
2034
- }
2035
- for (const item of set2) {
2036
- if (set1.has(item)) {
2037
- return true;
2038
- }
2039
- }
2040
- return false;
2041
- }
2042
- function removeConflictingTransitions(enabledTransitions, stateNodeSet, historyValue) {
2043
- const filteredTransitions = new Set();
2044
- for (const t1 of enabledTransitions) {
2045
- let t1Preempted = false;
2046
- const transitionsToRemove = new Set();
2047
- for (const t2 of filteredTransitions) {
2048
- if (hasIntersection(computeExitSet([t1], stateNodeSet, historyValue), computeExitSet([t2], stateNodeSet, historyValue))) {
2049
- if (isDescendant(t1.source, t2.source)) {
2050
- transitionsToRemove.add(t2);
2051
- } else {
2052
- t1Preempted = true;
2053
- break;
2054
- }
2055
- }
2056
- }
2057
- if (!t1Preempted) {
2058
- for (const t3 of transitionsToRemove) {
2059
- filteredTransitions.delete(t3);
2060
- }
2061
- filteredTransitions.add(t1);
2062
- }
2063
- }
2064
- return Array.from(filteredTransitions);
2065
- }
2066
- function findLeastCommonAncestor(stateNodes) {
2067
- const [head, ...tail] = stateNodes;
2068
- for (const ancestor of getProperAncestors(head, undefined)) {
2069
- if (tail.every(sn => isDescendant(sn, ancestor))) {
2070
- return ancestor;
2071
- }
2072
- }
2073
- }
2074
- function getEffectiveTargetStates(transition, historyValue) {
2075
- if (!transition.target) {
2076
- return [];
2077
- }
2078
- const targets = new Set();
2079
- for (const targetNode of transition.target) {
2080
- if (isHistoryNode(targetNode)) {
2081
- if (historyValue[targetNode.id]) {
2082
- for (const node of historyValue[targetNode.id]) {
2083
- targets.add(node);
2084
- }
2085
- } else {
2086
- for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) {
2087
- targets.add(node);
2088
- }
2089
- }
2090
- } else {
2091
- targets.add(targetNode);
2092
- }
2093
- }
2094
- return [...targets];
2095
- }
2096
- function getTransitionDomain(transition, historyValue) {
2097
- const targetStates = getEffectiveTargetStates(transition, historyValue);
2098
- if (!targetStates) {
2099
- return;
2100
- }
2101
- if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
2102
- return transition.source;
2103
- }
2104
- const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
2105
- if (lca) {
2106
- return lca;
2107
- }
2108
-
2109
- // at this point we know that it's a root transition since LCA couldn't be found
2110
- if (transition.reenter) {
2111
- return;
2112
- }
2113
- return transition.source.machine.root;
2114
- }
2115
- function computeExitSet(transitions, stateNodeSet, historyValue) {
2116
- const statesToExit = new Set();
2117
- for (const t of transitions) {
2118
- if (t.target?.length) {
2119
- const domain = getTransitionDomain(t, historyValue);
2120
- if (t.reenter && t.source === domain) {
2121
- statesToExit.add(domain);
2122
- }
2123
- for (const stateNode of stateNodeSet) {
2124
- if (isDescendant(stateNode, domain)) {
2125
- statesToExit.add(stateNode);
2126
- }
2127
- }
2128
- }
2129
- }
2130
- return [...statesToExit];
2131
- }
2132
- function areStateNodeCollectionsEqual(prevStateNodes, nextStateNodeSet) {
2133
- if (prevStateNodes.length !== nextStateNodeSet.size) {
2134
- return false;
2135
- }
2136
- for (const node of prevStateNodes) {
2137
- if (!nextStateNodeSet.has(node)) {
2138
- return false;
2139
- }
2140
- }
2141
- return true;
2142
- }
2143
- function initialMicrostep(root, preInitialState, actorScope, initEvent, internalQueue) {
2144
- return microstep([{
2145
- target: [...getInitialStateNodes(root)],
2146
- source: root,
2147
- reenter: true,
2148
- actions: [],
2149
- eventType: null,
2150
- toJSON: null
2151
- }], preInitialState, actorScope, initEvent, true, internalQueue);
2152
- }
2153
-
2154
- /** https://www.w3.org/TR/scxml/#microstepProcedure */
2155
- function microstep(transitions, currentSnapshot, actorScope, event, isInitial, internalQueue) {
2156
- const actions = [];
2157
- if (!transitions.length) {
2158
- return [currentSnapshot, actions];
2159
- }
2160
- const originalExecutor = actorScope.actionExecutor;
2161
- actorScope.actionExecutor = action => {
2162
- actions.push(action);
2163
- originalExecutor(action);
2164
- };
2165
- try {
2166
- const mutStateNodeSet = new Set(currentSnapshot._nodes);
2167
- let historyValue = currentSnapshot.historyValue;
2168
- const filteredTransitions = removeConflictingTransitions(transitions, mutStateNodeSet, historyValue);
2169
- let nextState = currentSnapshot;
2170
-
2171
- // Exit states
2172
- if (!isInitial) {
2173
- [nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutStateNodeSet, historyValue, internalQueue, actorScope.actionExecutor);
2174
- }
2175
-
2176
- // Execute transition content
2177
- nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap(t => t.actions), internalQueue, undefined);
2178
-
2179
- // Enter states
2180
- nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutStateNodeSet, internalQueue, historyValue, isInitial);
2181
- const nextStateNodes = [...mutStateNodeSet];
2182
- if (nextState.status === 'done') {
2183
- nextState = resolveActionsAndContext(nextState, event, actorScope, nextStateNodes.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue, undefined);
2184
- }
2185
-
2186
- // eslint-disable-next-line no-useless-catch
2187
- try {
2188
- if (historyValue === currentSnapshot.historyValue && areStateNodeCollectionsEqual(currentSnapshot._nodes, mutStateNodeSet)) {
2189
- return [nextState, actions];
2190
- }
2191
- return [cloneMachineSnapshot(nextState, {
2192
- _nodes: nextStateNodes,
2193
- historyValue
2194
- }), actions];
2195
- } catch (e) {
2196
- // TODO: Refactor this once proper error handling is implemented.
2197
- // See https://github.com/statelyai/rfcs/pull/4
2198
- throw e;
2199
- }
2200
- } finally {
2201
- actorScope.actionExecutor = originalExecutor;
2202
- }
2203
- }
2204
- function getMachineOutput(snapshot, event, actorScope, rootNode, rootCompletionNode) {
2205
- if (rootNode.output === undefined) {
2206
- return;
2207
- }
2208
- const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output !== undefined && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, snapshot.context, event, actorScope.self) : undefined);
2209
- return resolveOutput(rootNode.output, snapshot.context, doneStateEvent, actorScope.self);
2210
- }
2211
- function enterStates(currentSnapshot, event, actorScope, filteredTransitions, mutStateNodeSet, internalQueue, historyValue, isInitial) {
2212
- let nextSnapshot = currentSnapshot;
2213
- const statesToEnter = new Set();
2214
- // those are states that were directly targeted or indirectly targeted by the explicit target
2215
- // in other words, those are states for which initial actions should be executed
2216
- // when we target `#deep_child` initial actions of its ancestors shouldn't be executed
2217
- const statesForDefaultEntry = new Set();
2218
- computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
2219
-
2220
- // In the initial state, the root state node is "entered".
2221
- if (isInitial) {
2222
- statesForDefaultEntry.add(currentSnapshot.machine.root);
2223
- }
2224
- const completedNodes = new Set();
2225
- for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
2226
- mutStateNodeSet.add(stateNodeToEnter);
2227
- const actions = [];
2228
-
2229
- // Add entry actions
2230
- actions.push(...stateNodeToEnter.entry);
2231
- for (const invokeDef of stateNodeToEnter.invoke) {
2232
- actions.push(spawnChild(invokeDef.src, {
2233
- ...invokeDef,
2234
- syncSnapshot: !!invokeDef.onSnapshot
2235
- }));
2236
- }
2237
- if (statesForDefaultEntry.has(stateNodeToEnter)) {
2238
- const initialActions = stateNodeToEnter.initial.actions;
2239
- actions.push(...initialActions);
2240
- }
2241
- nextSnapshot = resolveActionsAndContext(nextSnapshot, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
2242
- if (stateNodeToEnter.type === 'final') {
2243
- const parent = stateNodeToEnter.parent;
2244
- let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
2245
- let rootCompletionNode = ancestorMarker || stateNodeToEnter;
2246
- if (parent?.type === 'compound') {
2247
- internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output !== undefined ? resolveOutput(stateNodeToEnter.output, nextSnapshot.context, event, actorScope.self) : undefined));
2248
- }
2249
- while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutStateNodeSet, ancestorMarker)) {
2250
- completedNodes.add(ancestorMarker);
2251
- internalQueue.push(createDoneStateEvent(ancestorMarker.id));
2252
- rootCompletionNode = ancestorMarker;
2253
- ancestorMarker = ancestorMarker.parent;
2254
- }
2255
- if (ancestorMarker) {
2256
- continue;
2257
- }
2258
- nextSnapshot = cloneMachineSnapshot(nextSnapshot, {
2259
- status: 'done',
2260
- output: getMachineOutput(nextSnapshot, event, actorScope, nextSnapshot.machine.root, rootCompletionNode)
2261
- });
2262
- }
2263
- }
2264
- return nextSnapshot;
2265
- }
2266
- function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
2267
- for (const t of transitions) {
2268
- const domain = getTransitionDomain(t, historyValue);
2269
- for (const s of t.target || []) {
2270
- if (!isHistoryNode(s) && (
2271
- // if the target is different than the source then it will *definitely* be entered
2272
- t.source !== s ||
2273
- // we know that the domain can't lie within the source
2274
- // 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
2275
- t.source !== domain ||
2276
- // reentering transitions always enter the target, even if it's the source itself
2277
- t.reenter)) {
2278
- statesToEnter.add(s);
2279
- statesForDefaultEntry.add(s);
2280
- }
2281
- addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
2282
- }
2283
- const targetStates = getEffectiveTargetStates(t, historyValue);
2284
- for (const s of targetStates) {
2285
- const ancestors = getProperAncestors(s, domain);
2286
- if (domain?.type === 'parallel') {
2287
- ancestors.push(domain);
2288
- }
2289
- addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? undefined : domain);
2290
- }
2291
- }
2292
- }
2293
- function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEntry, statesToEnter) {
2294
- if (isHistoryNode(stateNode)) {
2295
- if (historyValue[stateNode.id]) {
2296
- const historyStateNodes = historyValue[stateNode.id];
2297
- for (const s of historyStateNodes) {
2298
- statesToEnter.add(s);
2299
- addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
2300
- }
2301
- for (const s of historyStateNodes) {
2302
- addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
2303
- }
2304
- } else {
2305
- const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
2306
- for (const s of historyDefaultTransition.target) {
2307
- statesToEnter.add(s);
2308
- if (historyDefaultTransition === stateNode.parent?.initial) {
2309
- statesForDefaultEntry.add(stateNode.parent);
2310
- }
2311
- addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
2312
- }
2313
- for (const s of historyDefaultTransition.target) {
2314
- addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
2315
- }
2316
- }
2317
- } else {
2318
- if (stateNode.type === 'compound') {
2319
- const [initialState] = stateNode.initial.target;
2320
- if (!isHistoryNode(initialState)) {
2321
- statesToEnter.add(initialState);
2322
- statesForDefaultEntry.add(initialState);
2323
- }
2324
- addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
2325
- addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
2326
- } else {
2327
- if (stateNode.type === 'parallel') {
2328
- for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
2329
- if (![...statesToEnter].some(s => isDescendant(s, child))) {
2330
- if (!isHistoryNode(child)) {
2331
- statesToEnter.add(child);
2332
- statesForDefaultEntry.add(child);
2333
- }
2334
- addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
2335
- }
2336
- }
2337
- }
2338
- }
2339
- }
2340
- }
2341
- function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
2342
- for (const anc of ancestors) {
2343
- if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) {
2344
- statesToEnter.add(anc);
2345
- }
2346
- if (anc.type === 'parallel') {
2347
- for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
2348
- if (![...statesToEnter].some(s => isDescendant(s, child))) {
2349
- statesToEnter.add(child);
2350
- addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
2351
- }
2352
- }
2353
- }
2354
- }
2355
- }
2356
- function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
2357
- addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
2358
- }
2359
- function exitStates(currentSnapshot, event, actorScope, transitions, mutStateNodeSet, historyValue, internalQueue, _actionExecutor) {
2360
- let nextSnapshot = currentSnapshot;
2361
- const statesToExit = computeExitSet(transitions, mutStateNodeSet, historyValue);
2362
- statesToExit.sort((a, b) => b.order - a.order);
2363
- let changedHistory;
2364
-
2365
- // From SCXML algorithm: https://www.w3.org/TR/scxml/#exitStates
2366
- for (const exitStateNode of statesToExit) {
2367
- for (const historyNode of getHistoryNodes(exitStateNode)) {
2368
- let predicate;
2369
- if (historyNode.history === 'deep') {
2370
- predicate = sn => isAtomicStateNode(sn) && isDescendant(sn, exitStateNode);
2371
- } else {
2372
- predicate = sn => {
2373
- return sn.parent === exitStateNode;
2374
- };
2375
- }
2376
- changedHistory ??= {
2377
- ...historyValue
2378
- };
2379
- changedHistory[historyNode.id] = Array.from(mutStateNodeSet).filter(predicate);
2380
- }
2381
- }
2382
- for (const s of statesToExit) {
2383
- nextSnapshot = resolveActionsAndContext(nextSnapshot, event, actorScope, [...s.exit, ...s.invoke.map(def => stopChild(def.id))], internalQueue, undefined);
2384
- mutStateNodeSet.delete(s);
2385
- }
2386
- return [nextSnapshot, changedHistory || historyValue];
2387
- }
2388
- function getAction(machine, actionType) {
2389
- return machine.implementations.actions[actionType];
2390
- }
2391
- function resolveAndExecuteActionsWithContext(currentSnapshot, event, actorScope, actions, extra, retries) {
2392
- const {
2393
- machine
2394
- } = currentSnapshot;
2395
- let intermediateSnapshot = currentSnapshot;
2396
- for (const action of actions) {
2397
- const isInline = typeof action === 'function';
2398
- const resolvedAction = isInline ? action :
2399
- // the existing type of `.actions` assumes non-nullable `TExpressionAction`
2400
- // it's fine to cast this here to get a common type and lack of errors in the rest of the code
2401
- // our logic below makes sure that we call those 2 "variants" correctly
2402
-
2403
- getAction(machine, typeof action === 'string' ? action : action.type);
2404
- const actionArgs = {
2405
- context: intermediateSnapshot.context,
2406
- event,
2407
- self: actorScope.self,
2408
- system: actorScope.system
2409
- };
2410
- const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
2411
- context: intermediateSnapshot.context,
2412
- event
2413
- }) : action.params : undefined;
2414
- if (!resolvedAction || !('resolve' in resolvedAction)) {
2415
- actorScope.actionExecutor({
2416
- type: typeof action === 'string' ? action : typeof action === 'object' ? action.type : action.name || '(anonymous)',
2417
- info: actionArgs,
2418
- params: actionParams,
2419
- exec: resolvedAction
2420
- });
2421
- continue;
2422
- }
2423
- const builtinAction = resolvedAction;
2424
- const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateSnapshot, actionArgs, actionParams, resolvedAction,
2425
- // this holds all params
2426
- extra);
2427
- intermediateSnapshot = nextState;
2428
- if ('retryResolve' in builtinAction) {
2429
- retries?.push([builtinAction, params]);
2430
- }
2431
- if ('execute' in builtinAction) {
2432
- actorScope.actionExecutor({
2433
- type: builtinAction.type,
2434
- info: actionArgs,
2435
- params,
2436
- exec: builtinAction.execute.bind(null, actorScope, params)
2437
- });
2438
- }
2439
- if (actions) {
2440
- intermediateSnapshot = resolveAndExecuteActionsWithContext(intermediateSnapshot, event, actorScope, actions, extra, retries);
2441
- }
2442
- }
2443
- return intermediateSnapshot;
2444
- }
2445
- function resolveActionsAndContext(currentSnapshot, event, actorScope, actions, internalQueue, deferredActorIds) {
2446
- const retries = deferredActorIds ? [] : undefined;
2447
- const nextState = resolveAndExecuteActionsWithContext(currentSnapshot, event, actorScope, actions, {
2448
- internalQueue,
2449
- deferredActorIds
2450
- }, retries);
2451
- retries?.forEach(([builtinAction, params]) => {
2452
- builtinAction.retryResolve(actorScope, nextState, params);
2453
- });
2454
- return nextState;
2455
- }
2456
- function macrostep(snapshot, event, actorScope, internalQueue) {
2457
- let nextSnapshot = snapshot;
2458
- const microsteps = [];
2459
- function addMicrostep(step, event, transitions) {
2460
- actorScope.system._sendInspectionEvent({
2461
- type: '@xstate.microstep',
2462
- actorRef: actorScope.self,
2463
- event,
2464
- snapshot: step[0],
2465
- _transitions: transitions
2466
- });
2467
- microsteps.push(step);
2468
- }
2469
-
2470
- // Handle stop event
2471
- if (event.type === XSTATE_STOP) {
2472
- nextSnapshot = cloneMachineSnapshot(stopChildren(nextSnapshot, event, actorScope), {
2473
- status: 'stopped'
2474
- });
2475
- addMicrostep([nextSnapshot, []], event, []);
2476
- return {
2477
- snapshot: nextSnapshot,
2478
- microsteps
2479
- };
2480
- }
2481
- let nextEvent = event;
2482
-
2483
- // Assume the state is at rest (no raised events)
2484
- // Determine the next state based on the next microstep
2485
- if (nextEvent.type !== XSTATE_INIT) {
2486
- const currentEvent = nextEvent;
2487
- const isErr = isErrorActorEvent(currentEvent);
2488
- const transitions = selectTransitions(currentEvent, nextSnapshot);
2489
- if (isErr && !transitions.length) {
2490
- // TODO: we should likely only allow transitions selected by very explicit descriptors
2491
- // `*` shouldn't be matched, likely `xstate.error.*` shouldn't be either
2492
- // similarly `xstate.error.actor.*` and `xstate.error.actor.todo.*` have to be considered too
2493
- nextSnapshot = cloneMachineSnapshot(snapshot, {
2494
- status: 'error',
2495
- error: currentEvent.error
2496
- });
2497
- addMicrostep([nextSnapshot, []], currentEvent, []);
2498
- return {
2499
- snapshot: nextSnapshot,
2500
- microsteps
2501
- };
2502
- }
2503
- const step = microstep(transitions, snapshot, actorScope, nextEvent, false,
2504
- // isInitial
2505
- internalQueue);
2506
- nextSnapshot = step[0];
2507
- addMicrostep(step, currentEvent, transitions);
2508
- }
2509
- let shouldSelectEventlessTransitions = true;
2510
- while (nextSnapshot.status === 'active') {
2511
- let enabledTransitions = shouldSelectEventlessTransitions ? selectEventlessTransitions(nextSnapshot, nextEvent) : [];
2512
-
2513
- // eventless transitions should always be selected after selecting *regular* transitions
2514
- // by assigning `undefined` to `previousState` we ensure that `shouldSelectEventlessTransitions` gets always computed to true in such a case
2515
- const previousState = enabledTransitions.length ? nextSnapshot : undefined;
2516
- if (!enabledTransitions.length) {
2517
- if (!internalQueue.length) {
2518
- break;
2519
- }
2520
- nextEvent = internalQueue.shift();
2521
- enabledTransitions = selectTransitions(nextEvent, nextSnapshot);
2522
- }
2523
- const step = microstep(enabledTransitions, nextSnapshot, actorScope, nextEvent, false, internalQueue);
2524
- nextSnapshot = step[0];
2525
- shouldSelectEventlessTransitions = nextSnapshot !== previousState;
2526
- addMicrostep(step, nextEvent, enabledTransitions);
2527
- }
2528
- if (nextSnapshot.status !== 'active') {
2529
- stopChildren(nextSnapshot, nextEvent, actorScope);
2530
- }
2531
- return {
2532
- snapshot: nextSnapshot,
2533
- microsteps
2534
- };
2535
- }
2536
- function stopChildren(nextState, event, actorScope) {
2537
- return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map(child => stopChild(child)), [], undefined);
2538
- }
2539
- function selectTransitions(event, nextState) {
2540
- return nextState.machine.getTransitionData(nextState, event);
2541
- }
2542
- function selectEventlessTransitions(nextState, event) {
2543
- const enabledTransitionSet = new Set();
2544
- const atomicStates = nextState._nodes.filter(isAtomicStateNode);
2545
- for (const stateNode of atomicStates) {
2546
- loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, undefined))) {
2547
- if (!s.always) {
2548
- continue;
2549
- }
2550
- for (const transition of s.always) {
2551
- if (transition.guard === undefined || evaluateGuard(transition.guard, nextState.context, event, nextState)) {
2552
- enabledTransitionSet.add(transition);
2553
- break loop;
2554
- }
2555
- }
2556
- }
2557
- }
2558
- return removeConflictingTransitions(Array.from(enabledTransitionSet), new Set(nextState._nodes), nextState.historyValue);
2559
- }
2560
-
2561
- /**
2562
- * Resolves a partial state value with its full representation in the state
2563
- * node's machine.
2564
- *
2565
- * @param stateValue The partial state value to resolve.
2566
- */
2567
- function resolveStateValue(rootNode, stateValue) {
2568
- const allStateNodes = getAllStateNodes(getStateNodes(rootNode, stateValue));
2569
- return getStateValue(rootNode, [...allStateNodes]);
2570
- }
2571
-
2572
- function isMachineSnapshot(value) {
2573
- return !!value && typeof value === 'object' && 'machine' in value && 'value' in value;
2574
- }
2575
- const machineSnapshotMatches = function matches(testValue) {
2576
- return matchesState(testValue, this.value);
2577
- };
2578
- const machineSnapshotHasTag = function hasTag(tag) {
2579
- return this.tags.has(tag);
2580
- };
2581
- const machineSnapshotCan = function can(event) {
2582
- const transitionData = this.machine.getTransitionData(this, event);
2583
- return !!transitionData?.length &&
2584
- // Check that at least one transition is not forbidden
2585
- transitionData.some(t => t.target !== undefined || t.actions.length);
2586
- };
2587
- const machineSnapshotToJSON = function toJSON() {
2588
- const {
2589
- _nodes: nodes,
2590
- tags,
2591
- machine,
2592
- getMeta,
2593
- toJSON,
2594
- can,
2595
- hasTag,
2596
- matches,
2597
- ...jsonValues
2598
- } = this;
2599
- return {
2600
- ...jsonValues,
2601
- tags: Array.from(tags)
2602
- };
2603
- };
2604
- const machineSnapshotGetMeta = function getMeta() {
2605
- return this._nodes.reduce((acc, stateNode) => {
2606
- if (stateNode.meta !== undefined) {
2607
- acc[stateNode.id] = stateNode.meta;
2608
- }
2609
- return acc;
2610
- }, {});
2611
- };
2612
- function createMachineSnapshot(config, machine) {
2613
- return {
2614
- status: config.status,
2615
- output: config.output,
2616
- error: config.error,
2617
- machine,
2618
- context: config.context,
2619
- _nodes: config._nodes,
2620
- value: getStateValue(machine.root, config._nodes),
2621
- tags: new Set(config._nodes.flatMap(sn => sn.tags)),
2622
- children: config.children,
2623
- historyValue: config.historyValue || {},
2624
- matches: machineSnapshotMatches,
2625
- hasTag: machineSnapshotHasTag,
2626
- can: machineSnapshotCan,
2627
- getMeta: machineSnapshotGetMeta,
2628
- toJSON: machineSnapshotToJSON
2629
- };
2630
- }
2631
- function cloneMachineSnapshot(snapshot, config = {}) {
2632
- return createMachineSnapshot({
2633
- ...snapshot,
2634
- ...config
2635
- }, snapshot.machine);
2636
- }
2637
- function serializeHistoryValue(historyValue) {
2638
- if (typeof historyValue !== 'object' || historyValue === null) {
2639
- return {};
2640
- }
2641
- const result = {};
2642
- for (const key in historyValue) {
2643
- const value = historyValue[key];
2644
- if (Array.isArray(value)) {
2645
- result[key] = value.map(item => ({
2646
- id: item.id
2647
- }));
2648
- }
2649
- }
2650
- return result;
2651
- }
2652
- function getPersistedSnapshot(snapshot, options) {
2653
- const {
2654
- _nodes: nodes,
2655
- tags,
2656
- machine,
2657
- children,
2658
- context,
2659
- can,
2660
- hasTag,
2661
- matches,
2662
- getMeta,
2663
- toJSON,
2664
- ...jsonValues
2665
- } = snapshot;
2666
- const childrenJson = {};
2667
- for (const id in children) {
2668
- const child = children[id];
2669
- childrenJson[id] = {
2670
- snapshot: child.getPersistedSnapshot(options),
2671
- src: child.src,
2672
- systemId: child.systemId,
2673
- syncSnapshot: child._syncSnapshot
2674
- };
2675
- }
2676
- const persisted = {
2677
- ...jsonValues,
2678
- context: persistContext(context),
2679
- children: childrenJson,
2680
- historyValue: serializeHistoryValue(jsonValues.historyValue)
2681
- };
2682
- return persisted;
2683
- }
2684
- function persistContext(contextPart) {
2685
- let copy;
2686
- for (const key in contextPart) {
2687
- const value = contextPart[key];
2688
- if (value && typeof value === 'object') {
2689
- if ('sessionId' in value && 'send' in value && 'ref' in value) {
2690
- copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
2691
- ...contextPart
2692
- };
2693
- copy[key] = {
2694
- xstate$$type: $$ACTOR_TYPE,
2695
- id: value.id
2696
- };
2697
- } else {
2698
- const result = persistContext(value);
2699
- if (result !== value) {
2700
- copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
2701
- ...contextPart
2702
- };
2703
- copy[key] = result;
2704
- }
2705
- }
2706
- }
2707
- }
2708
- return copy ?? contextPart;
2709
- }
2710
-
2711
- function resolveRaise(_, snapshot, args, actionParams, {
2712
- event: eventOrExpr,
2713
- id,
2714
- delay
2715
- }, {
2716
- internalQueue
2717
- }) {
2718
- const delaysMap = snapshot.machine.implementations.delays;
2719
- if (typeof eventOrExpr === 'string') {
2720
- throw new Error(
2721
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
2722
- `Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
2723
- }
2724
- const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
2725
- let resolvedDelay;
2726
- if (typeof delay === 'string') {
2727
- const configDelay = delaysMap && delaysMap[delay];
2728
- resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
2729
- } else {
2730
- resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
2731
- }
2732
- if (typeof resolvedDelay !== 'number') {
2733
- internalQueue.push(resolvedEvent);
2734
- }
2735
- return [snapshot, {
2736
- event: resolvedEvent,
2737
- id,
2738
- delay: resolvedDelay
2739
- }, undefined];
2740
- }
2741
- function executeRaise(actorScope, params) {
2742
- const {
2743
- event,
2744
- delay,
2745
- id
2746
- } = params;
2747
- if (typeof delay === 'number') {
2748
- actorScope.defer(() => {
2749
- const self = actorScope.self;
2750
- actorScope.system.scheduler.schedule(self, self, event, delay, id);
2751
- });
2752
- return;
2753
- }
2754
- }
2755
- /**
2756
- * Raises an event. This places the event in the internal event queue, so that
2757
- * the event is immediately consumed by the machine in the current step.
2758
- *
2759
- * @param eventType The event to raise.
2760
- */
2761
- function raise(eventOrExpr, options) {
2762
- function raise(_args, _params) {
2763
- }
2764
- raise.type = 'xstate.raise';
2765
- raise.event = eventOrExpr;
2766
- raise.id = options?.id;
2767
- raise.delay = options?.delay;
2768
- raise.resolve = resolveRaise;
2769
- raise.execute = executeRaise;
2770
- return raise;
2771
- }
2772
-
2773
- raiseF051f097_cjs.$$ACTOR_TYPE = $$ACTOR_TYPE;
2774
- raiseF051f097_cjs.Actor = Actor;
2775
- raiseF051f097_cjs.NULL_EVENT = NULL_EVENT;
2776
- raiseF051f097_cjs.ProcessingStatus = ProcessingStatus;
2777
- raiseF051f097_cjs.STATE_DELIMITER = STATE_DELIMITER;
2778
- raiseF051f097_cjs.XSTATE_ERROR = XSTATE_ERROR;
2779
- raiseF051f097_cjs.XSTATE_STOP = XSTATE_STOP;
2780
- raiseF051f097_cjs.and = and;
2781
- raiseF051f097_cjs.cancel = cancel;
2782
- raiseF051f097_cjs.cloneMachineSnapshot = cloneMachineSnapshot;
2783
- raiseF051f097_cjs.createActor = createActor;
2784
- raiseF051f097_cjs.createErrorActorEvent = createErrorActorEvent;
2785
- raiseF051f097_cjs.createInitEvent = createInitEvent;
2786
- raiseF051f097_cjs.createInvokeId = createInvokeId;
2787
- raiseF051f097_cjs.createMachineSnapshot = createMachineSnapshot;
2788
- raiseF051f097_cjs.evaluateGuard = evaluateGuard;
2789
- raiseF051f097_cjs.formatInitialTransition = formatInitialTransition;
2790
- raiseF051f097_cjs.formatRouteTransitions = formatRouteTransitions;
2791
- raiseF051f097_cjs.formatTransition = formatTransition;
2792
- raiseF051f097_cjs.formatTransitions = formatTransitions;
2793
- raiseF051f097_cjs.getAllOwnEventDescriptors = getAllOwnEventDescriptors;
2794
- raiseF051f097_cjs.getAllStateNodes = getAllStateNodes;
2795
- raiseF051f097_cjs.getCandidates = getCandidates;
2796
- raiseF051f097_cjs.getDelayedTransitions = getDelayedTransitions;
2797
- raiseF051f097_cjs.getPersistedSnapshot = getPersistedSnapshot;
2798
- raiseF051f097_cjs.getProperAncestors = getProperAncestors;
2799
- raiseF051f097_cjs.getStateNodeByPath = getStateNodeByPath;
2800
- raiseF051f097_cjs.getStateNodes = getStateNodes;
2801
- raiseF051f097_cjs.initialMicrostep = initialMicrostep;
2802
- raiseF051f097_cjs.interpret = interpret;
2803
- raiseF051f097_cjs.isAtomicStateNode = isAtomicStateNode;
2804
- raiseF051f097_cjs.isInFinalState = isInFinalState;
2805
- raiseF051f097_cjs.isMachineSnapshot = isMachineSnapshot;
2806
- raiseF051f097_cjs.isStateId = isStateId;
2807
- raiseF051f097_cjs.macrostep = macrostep;
2808
- raiseF051f097_cjs.mapValues = mapValues;
2809
- raiseF051f097_cjs.matchesEventDescriptor = matchesEventDescriptor;
2810
- raiseF051f097_cjs.matchesState = matchesState;
2811
- raiseF051f097_cjs.not = not;
2812
- raiseF051f097_cjs.or = or;
2813
- raiseF051f097_cjs.pathToStateValue = pathToStateValue;
2814
- raiseF051f097_cjs.raise = raise;
2815
- raiseF051f097_cjs.resolveActionsAndContext = resolveActionsAndContext;
2816
- raiseF051f097_cjs.resolveReferencedActor = resolveReferencedActor;
2817
- raiseF051f097_cjs.resolveStateValue = resolveStateValue;
2818
- raiseF051f097_cjs.spawnChild = spawnChild;
2819
- raiseF051f097_cjs.stateIn = stateIn;
2820
- raiseF051f097_cjs.stop = stop;
2821
- raiseF051f097_cjs.stopChild = stopChild;
2822
- raiseF051f097_cjs.toArray = toArray;
2823
- raiseF051f097_cjs.toObserver = toObserver;
2824
- raiseF051f097_cjs.toStatePath = toStatePath;
2825
- raiseF051f097_cjs.toTransitionConfigArray = toTransitionConfigArray;
2826
- raiseF051f097_cjs.transitionNode = transitionNode;
2827
- return raiseF051f097_cjs;
2828
- }
2829
-
2830
- export { requireRaiseF051f097_cjs as __require };