xstate-statemachine 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,31 @@
1
+ # src/xstate_statemachine/__init__.py
2
+
3
+ __version__ = "0.2.0" # Version bump for new features
4
+
5
+ from .factory import create_machine
6
+ from .interpreter import Interpreter
7
+ from .machine_logic import MachineLogic
8
+ from .events import Event
9
+ from .plugins import PluginBase, LoggingInspector
10
+ from .exceptions import (
11
+ XStateMachineError,
12
+ InvalidConfigError,
13
+ StateNotFoundError,
14
+ ImplementationMissingError,
15
+ ActorSpawningError,
16
+ )
17
+
18
+ # This is the public API of the library.
19
+ __all__ = [
20
+ "create_machine",
21
+ "Interpreter",
22
+ "MachineLogic",
23
+ "Event",
24
+ "PluginBase",
25
+ "LoggingInspector",
26
+ "XStateMachineError",
27
+ "InvalidConfigError",
28
+ "StateNotFoundError",
29
+ "ImplementationMissingError",
30
+ "ActorSpawningError",
31
+ ]
@@ -0,0 +1,39 @@
1
+ # src/xstate_statemachine/events.py
2
+ from typing import Any, Dict, Literal, NamedTuple
3
+
4
+
5
+ # -----------------------------------------------------------------------------
6
+ # ✉️ Event Definitions
7
+ # -----------------------------------------------------------------------------
8
+ # Standardizing event structures within the machine ensures consistency and
9
+ # clear communication between components.
10
+ # -----------------------------------------------------------------------------
11
+
12
+
13
+ class Event(NamedTuple):
14
+ """Represents an event sent to the machine."""
15
+
16
+ type: str
17
+ payload: Dict[str, Any] = {}
18
+
19
+
20
+ class DoneEvent(NamedTuple):
21
+ """
22
+ Represents the completion of an invoked service.
23
+
24
+ The type follows the convention 'done.invoke.<service_id>'.
25
+ """
26
+
27
+ type: str
28
+ data: Any
29
+ src: str
30
+
31
+
32
+ class AfterEvent(NamedTuple):
33
+ """
34
+ Represents the firing of a delayed transition.
35
+
36
+ The type follows the convention 'after.<delay>.<state_id>'.
37
+ """
38
+
39
+ type: str
@@ -0,0 +1,43 @@
1
+ # src/xstate_statemachine/exceptions.py
2
+
3
+ # -----------------------------------------------------------------------------
4
+ # 🚨 Custom Exceptions
5
+ # -----------------------------------------------------------------------------
6
+ # Defining specific exceptions improves error handling and makes the library's
7
+ # failure modes clearer to the user.
8
+ # -----------------------------------------------------------------------------
9
+
10
+
11
+ class XStateMachineError(Exception):
12
+ """Base exception for all errors raised by this library."""
13
+
14
+ pass
15
+
16
+
17
+ class InvalidConfigError(XStateMachineError):
18
+ """Raised when the machine configuration JSON is invalid."""
19
+
20
+ pass
21
+
22
+
23
+ class StateNotFoundError(XStateMachineError):
24
+ """Raised when a target state cannot be resolved."""
25
+
26
+ def __init__(self, target: str, reference_id: str):
27
+ self.target = target
28
+ self.reference_id = reference_id
29
+ super().__init__(
30
+ f"Could not resolve target state '{target}' from state '{reference_id}'."
31
+ )
32
+
33
+
34
+ class ImplementationMissingError(XStateMachineError):
35
+ """Raised when an action, guard, or service implementation is missing."""
36
+
37
+ pass
38
+
39
+
40
+ class ActorSpawningError(XStateMachineError):
41
+ """Raised when there is an error spawning or communicating with an actor."""
42
+
43
+ pass
@@ -0,0 +1,46 @@
1
+ # src/xstate_statemachine/factory.py
2
+ from typing import Any, Dict
3
+ from .models import MachineNode
4
+ from .machine_logic import MachineLogic
5
+ from .exceptions import InvalidConfigError
6
+ from .logger import logger
7
+
8
+ # -----------------------------------------------------------------------------
9
+ # 🏭 Machine Factory
10
+ # -----------------------------------------------------------------------------
11
+ # This module provides a single entry point for creating a state machine
12
+ # instance from its configuration, applying the Factory design pattern.
13
+ # -----------------------------------------------------------------------------
14
+
15
+
16
+ def create_machine(
17
+ config: Dict[str, Any], logic: MachineLogic = None
18
+ ) -> MachineNode:
19
+ """
20
+ Creates a state machine instance from a JSON-like config and implementation logic.
21
+
22
+ Args:
23
+ config: The state machine's definition.
24
+ logic: An object containing the implementations for all actions, guards, etc.
25
+
26
+ Returns:
27
+ The root node of the fully constructed state machine graph.
28
+
29
+ Raises:
30
+ InvalidConfigError: If the configuration is malformed.
31
+ """
32
+ if logic is None:
33
+ logic = MachineLogic()
34
+
35
+ machine_id = config.get("id")
36
+ logger.info(f"🏭 Creating machine with id: '{machine_id}'")
37
+ if (
38
+ not isinstance(config, dict)
39
+ or "states" not in config
40
+ or not machine_id
41
+ ):
42
+ raise InvalidConfigError(
43
+ "Invalid config: must be a dict with 'id' and 'states' keys."
44
+ )
45
+
46
+ return MachineNode(config, logic)