Documentation
¶
Overview ¶
Package hsm provides a powerful hierarchical state machine (HSM) implementation for Go.
Overview ¶
It enables modeling complex state-driven systems with features like hierarchical states, entry/exit actions, guard conditions, and event-driven transitions. The implementation follows the Unified DSK (Domain Specific Kit) specification, ensuring consistency across platforms.
Features ¶
- **Hierarchical States**: Support for nested states and regions.
- **Event-Driven**: Asynchronous event processing with context propagation.
- **Guards & Actions**: Flexible functional definitions for transition guards and state actions.
- **Type Safe**: Generics-based implementation for state context.
Usage ¶
Define your state machine structure and behavior using the declarative builder pattern:
type MyHSM struct {
hsm.HSM
counter int
}
model := hsm.Define(
"example",
hsm.State("foo"),
hsm.State("bar"),
hsm.Transition(
hsm.Trigger("moveToBar"),
hsm.Source("foo"),
hsm.Target("bar"),
),
hsm.Initial("foo"),
)
// Start the state machine
sm := hsm.Start(context.Background(), &MyHSM{}, &model)
sm.Dispatch(hsm.Event{Name: "moveToBar"})
Index ¶
- Constants
- Variables
- func AfterDispatch(ctx context.Context, hsm Instance, event Event) <-chan struct{}
- func AfterEntry[T stringLike](ctx context.Context, hsm Instance, state T) <-chan struct{}
- func AfterExecuted[T stringLike](ctx context.Context, hsm Instance, state T) <-chan struct{}
- func AfterExit[T stringLike](ctx context.Context, hsm Instance, state T) <-chan struct{}
- func AfterProcess(ctx context.Context, hsm Instance, maybeEvent ...Event) <-chan struct{}
- func Call[T stringLike](ctx context.Context, hsm Instance, name T, args ...any) (any, error)
- func Dispatch[T context.Context](ctx T, hsm Instance, event Event) <-chan struct{}
- func DispatchAll(ctx context.Context, event Event) <-chan struct{}
- func DispatchTo[T stringLike](ctx context.Context, event Event, maybeIds ...T) <-chan struct{}
- func Get[T stringLike](ctx context.Context, hsm Instance, name T) (any, bool)
- func ID(hsm Instance) string
- func IsAncestor(current, target string) bool
- func LCA(a, b string) string
- func Match[V stringLike, P stringLike](value V, patterns ...P) bool
- func Name(hsm Instance) string
- func New[T Instance](sm T, model *Model, maybeConfig ...Config) T
- func QualifiedName(hsm Instance) string
- func Restart(ctx context.Context, hsm Instance, maybeData ...any) <-chan struct{}
- func Set[T stringLike](ctx context.Context, hsm Instance, name T, value any) <-chan struct{}
- func Start[T Instance](ctx context.Context, sm T, maybeData ...any) T
- func Started[T Instance](ctx context.Context, sm T, model *Model, maybeConfig ...Config) T
- func Stop(ctx context.Context, hsm Instance) <-chan struct{}
- type AttributeChange
- type CallData
- type Clock
- type Config
- type Element
- type Event
- type EventDetail
- type ExpressionFunc
- type Group
- type HSM
- type Instance
- type Model
- type OperationFunc
- type RedefinableElement
- func Activity[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
- func After[T Instance](expr func(ctx context.Context, hsm T, event Event) time.Duration) RedefinableElement
- func At[T Instance](expr func(ctx context.Context, hsm T, event Event) time.Time) RedefinableElement
- func Attribute[T stringLike](name T, maybeDefault ...any) RedefinableElement
- func Choice[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func DeepHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func Defer[T interface{ ... }](events ...T) RedefinableElement
- func Effect[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
- func Entry[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
- func Every[T Instance](expr func(ctx context.Context, hsm T, event Event) time.Duration) RedefinableElement
- func Exit[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
- func Final[T stringLike](name T) RedefinableElement
- func Guard[T Instance](fn func(ctx context.Context, hsm T, event Event) bool) RedefinableElement
- func Initial(partialElements ...RedefinableElement) RedefinableElement
- func On[T interface{ ... }](events ...T) RedefinableElement
- func OnCall[T stringLike](name T) RedefinableElement
- func OnSet[T stringLike](name T) RedefinableElement
- func Operation[T stringLike](name T, fn any) RedefinableElement
- func ShallowHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
- func Source[T redefinableOrString](nameOrPartialElement T) RedefinableElement
- func State[T stringLike](name T, partialElements ...RedefinableElement) RedefinableElement
- func Target[T redefinableOrString](nameOrPartialElement T) RedefinableElement
- func Transition[T redefinableOrString](nameOrPartialElement T, partialElements ...RedefinableElement) RedefinableElement
- func When[T Instance](expr func(ctx context.Context, hsm T, event Event) <-chan struct{}) RedefinableElement
- type Snapshot
Constants ¶
const Version = "v1.1.0"
Version is the current semantic version of the hsm package.
Variables ¶
var ( // NullKind represents the absence of a kind or an uninitialized kind value. NullKind = kind.Make() // ElementKind is the base kind for all HSM elements. Every structural // component in the state machine hierarchy derives from ElementKind. ElementKind = kind.Make() // NamespaceKind represents elements that can contain named children, // enabling hierarchical name resolution for states and state machines. NamespaceKind = kind.Make(ElementKind) // VertexKind is the base kind for nodes in the state graph that can be // sources or targets of transitions, including states and pseudostates. VertexKind = kind.Make(ElementKind) // ConstraintKind represents guard conditions that control transition firing. ConstraintKind = kind.Make(ElementKind) // BehaviorKind represents executable behaviors such as entry, exit, and // transition effects that run during state machine execution. BehaviorKind = kind.Make(ElementKind) // ConcurrentKind represents behaviors that support concurrent execution // of multiple orthogonal regions. ConcurrentKind = kind.Make(BehaviorKind) // StateMachineKind represents the top-level state machine container that // owns regions, states, and transitions. Inherits from both ConcurrentKind // (for orthogonal regions) and NamespaceKind (for named child lookup). StateMachineKind = kind.Make(ConcurrentKind, NamespaceKind) // StateKind represents a state vertex that can contain nested regions, // entry/exit behaviors, and internal transitions. Inherits from VertexKind // (as a graph node) and NamespaceKind (as a container for child elements). StateKind = kind.Make(VertexKind, NamespaceKind) // RegionKind represents an orthogonal region within a composite state or // state machine, containing vertices and transitions. RegionKind = kind.Make(ElementKind) // TransitionKind is the base kind for all transitions between vertices, // representing edges in the state graph. TransitionKind = kind.Make(ElementKind) // InternalKind represents internal transitions that execute without // exiting or re-entering the containing state. InternalKind = kind.Make(TransitionKind) // ExternalKind represents external transitions that exit the source state // and enter the target state, triggering exit and entry behaviors. ExternalKind = kind.Make(TransitionKind) // LocalKind represents local transitions that do not exit the containing // composite state when transitioning between its substates. LocalKind = kind.Make(TransitionKind) // SelfKind represents self-transitions where the source and target are // the same state, triggering exit and re-entry of that state. SelfKind = kind.Make(TransitionKind) // EventKind is the base kind for all events that can trigger transitions // in the state machine. EventKind = kind.Make(ElementKind) // TimeEventKind represents events triggered after a specified duration, // used for timeout-based transitions. TimeEventKind = kind.Make(EventKind) // CompletionEventKind represents events automatically generated when a // state completes all its internal activities or reaches a final state. CompletionEventKind = kind.Make(EventKind) // ChangeEventKind represents events triggered when a boolean condition // becomes true, enabling data-driven transitions. ChangeEventKind = kind.Make(EventKind) // CallEventKind represents events triggered by method calls on the state // machine, enabling synchronous event dispatch. CallEventKind = kind.Make(EventKind) // ErrorEventKind represents events generated when an error occurs during // state machine execution. Inherits from CompletionEventKind as errors // typically complete the current processing. ErrorEventKind = kind.Make(CompletionEventKind) // PseudostateKind is the base kind for transient vertices that perform // control flow logic without representing stable states. PseudostateKind = kind.Make(VertexKind) // InitialKind represents the initial pseudostate that indicates the // default starting state when entering a region. InitialKind = kind.Make(PseudostateKind) // FinalStateKind represents a final state indicating that the enclosing // region has completed its execution. FinalStateKind = kind.Make(StateKind) // ChoiceKind represents a choice pseudostate that evaluates guards to // select among multiple outgoing transitions dynamically. ChoiceKind = kind.Make(PseudostateKind) // ShallowHistoryKind represents a shallow history pseudostate that // remembers the most recently active direct substate of its region. ShallowHistoryKind = kind.Make(PseudostateKind) // DeepHistoryKind represents a deep history pseudostate that remembers // the full active state configuration within its region recursively. DeepHistoryKind = kind.Make(PseudostateKind) // CustomKind represents user-defined element types for extending the // HSM framework with application-specific constructs. CustomKind = kind.Make(ElementKind) )
Kind constants define the HSM type hierarchy using bit-packed inheritance. Each Kind encodes its own ID and the IDs of its ancestor types, enabling efficient type checking via kind.Is(). The hierarchy follows UML state machine concepts where elements can inherit from multiple parent kinds.
var ( // ErrNilHSM is returned when an operation is attempted on a nil state machine. ErrNilHSM = errors.New("hsm is nil") // ErrInvalidState is returned when attempting to access or transition to an invalid state. ErrInvalidState = errors.New("invalid state") // ErrMissingHSM is returned when the HSM instance cannot be found in the context. ErrMissingHSM = errors.New("missing hsm in context") // ErrMissingOperation is returned when an operation callback is required but not provided. ErrMissingOperation = errors.New("missing operation") // ErrInvalidOperation is returned when an operation callback has an unsupported function signature. ErrInvalidOperation = errors.New("invalid operation") // ErrAlreadyStarted is returned when a state machine has already been started. ErrAlreadyStarted = errors.New("hsm already started") )
Error variables for common HSM error conditions. These sentinel errors can be checked using errors.Is for specific error handling.
var ( // InitialEvent is the completion event dispatched when a state machine starts. // It triggers the initial transition from the initial pseudostate to the first active state. InitialEvent = Event{ Name: "hsm_initial", Kind: CompletionEventKind, } // ErrorEvent is dispatched when an error occurs during state machine execution, // such as panics in concurrent behaviors or timeout errors. Use On(ErrorEvent) to handle errors. ErrorEvent = Event{ Name: "hsm_error", Kind: ErrorEventKind, } // AnyEvent is a wildcard event that matches any event not explicitly handled. // Transitions using On(AnyEvent) are only taken when no specific event transition matches. AnyEvent = Event{ Name: "*", Kind: EventKind, } // FinalEvent is the completion event dispatched when a state reaches its final state. // It triggers exit behaviors and propagates completion to parent regions. FinalEvent = Event{ Name: "hsm_final", Kind: CompletionEventKind, } // InfiniteDuration represents an unbounded duration for timeout operations. // Use this when a behavior should run indefinitely without timing out. InfiniteDuration = time.Duration(-1) )
Built-in event types and special duration constants used by the HSM runtime.
DefaultClock is used when Config.Clock does not override timer behavior.
Functions ¶
func AfterDispatch ¶
AfterDispatch returns a channel that closes when the specified event is dispatched. Unlike AfterProcess, this signals when the event is added to the queue, not when processing completes. Useful for confirming event delivery before processing begins.
func AfterEntry ¶
AfterEntry returns a channel that closes when the specified state is entered. The state parameter should be the fully qualified state path (e.g., "/parent/child"). Useful for waiting until a particular state becomes active.
func AfterExecuted ¶
AfterExecuted returns a channel that closes when the specified state's do-activity has completed execution. The state parameter should be the fully qualified state path. Useful for waiting until a state's background activity finishes.
func AfterExit ¶
AfterExit returns a channel that closes when the specified state is exited. The state parameter should be the fully qualified state path (e.g., "/parent/child"). Useful for waiting until a particular state is no longer active.
func AfterProcess ¶
AfterProcess returns a channel that closes when event processing completes. If an event is provided, the channel closes after that specific event is processed. If no event is provided, the channel closes after the next processing cycle completes. This is useful for synchronizing with state machine execution in tests or when coordinating external operations with state transitions.
func Dispatch ¶
Dispatch sends an event to a specific state machine instance. Returns a channel that closes when the event has been fully processed.
Example:
sm := hsm.Start(...)
done := sm.Dispatch(hsm.Event{Name: "start"})
<-done // Wait for event processing to complete
func DispatchAll ¶
DispatchAll sends an event to all state machine instances in the current context. Returns a channel that closes when all instances have processed the event. DispatchAll sends an event to all state machine instances in the current context. Returns a channel that closes when all instances have processed the event.
Example:
sm1 := hsm.Start(...)
sm2 := hsm.Start(...)
done := hsm.DispatchAll(context.Background(), hsm.Event{Name: "globalEvent"})
<-done // Wait for all instances to process the event
func DispatchTo ¶
func Get ¶ added in v1.0.3
Get reads an attribute value from the given state machine or from context.
func ID ¶
ID returns the unique identifier of a state machine instance. The ID is assigned when the state machine is created and remains constant throughout its lifecycle.
func IsAncestor ¶
IsAncestor checks whether current is an ancestor of target in the state hierarchy. It returns true if current appears in the path from the root to target's parent. Returns false if current equals target, or if either path is "." (relative root). The root path "/" is considered an ancestor of all other paths.
func LCA ¶
LCA finds the Lowest Common Ancestor between two qualified state names in a hierarchical state machine. It takes two qualified names 'a' and 'b' as strings and returns their closest common ancestor.
For example: - LCA("/s/s1", "/s/s2") returns "/s" - LCA("/s/s1", "/s/s1/s11") returns "/s/s1" - LCA("/s/s1", "/s/s1") returns "/s/s1"
func Match ¶
func Match[V stringLike, P stringLike](value V, patterns ...P) bool
Match provides a simple interface, handling basic cases directly and delegating complex matching to the match function.
func Name ¶
Name returns the simple name of a state machine instance (without path prefix). This extracts the base name from the qualified name, e.g., "child" from "/parent/child".
func QualifiedName ¶
QualifiedName returns the fully qualified name of a state machine instance. For nested state machines, this includes the parent path (e.g., "/parent/child"). For top-level state machines, this is typically just the name with a leading slash.
func Restart ¶
Restart stops a state machine and restarts it from the initial state. Optional data can be passed to reinitialize the state machine's data field. Returns a channel that closes when the restart completes.
func Started ¶
Started creates and starts a new state machine instance with the given model and configuration. The state machine will begin executing from its initial state.
Example:
model := hsm.Define(...)
sm := hsm.Started(context.Background(), &MyHSM{}, &model, hsm.Config{
Trace: func(ctx context.Context, step string, data ...any) (context.Context, func(...any)) {
log.Printf("Step: %s, Data: %v", step, data)
return ctx, func(...any) {}
},
Id: "my-hsm-1",
})
Types ¶
type AttributeChange ¶ added in v1.0.3
AttributeChange is the payload for attribute change events.
type Clock ¶ added in v1.0.8
type Clock struct {
After func(time.Duration) <-chan time.Time
NewTimer func(time.Duration) *time.Timer
}
Clock provides injectable timer functions used by the state machine runtime. Nil fields fall back to DefaultClock.
type Config ¶
type Config struct {
// ID is a unique identifier for the state machine instance.
ID string
// ActivityTimeout is the timeout for the state activity to terminate.
ActivityTimeout time.Duration
// Clock overrides the timer functions used by the state machine runtime.
Clock Clock
// Name is the name of the state machine.
Name string
// Data to be passed during initialization
Data any
}
Config provides configuration options for state machine initialization.
type Event ¶
type Event struct {
Kind uint64 `xml:"kind,attr" json:"kind"`
Name string `xml:"name,attr" json:"name"`
ID string `xml:"id,attr" json:"id"`
Source string `xml:"source,attr,omitempty" json:"source,omitempty"`
Target string `xml:"target,attr,omitempty" json:"target,omitempty"`
Data any `xml:"data" json:"data"`
Schema any `xml:"schema" json:"schema"`
}
type ExpressionFunc ¶ added in v1.0.6
ExpressionFunc is a function type that evaluates a condition on a state machine. Expressions are used for transition guards to determine whether a transition should be taken. They receive the current context, state machine instance, and the triggering event, returning true if the condition is satisfied.
type Group ¶ added in v1.0.6
type Group struct {
// contains filtered or unexported fields
}
Group is a composite instance that forwards operations to multiple instances. It flattens nested groups and broadcasts events to all members.
func NewGroup ¶ added in v1.0.6
NewGroup creates a new group from the provided instances. Nested groups are flattened.
type Instance ¶
type Instance interface {
// State returns the current state's qualified name.
State() string
Context() context.Context
Clock() Clock
// contains filtered or unexported methods
}
Instance represents an active state machine instance that can process events and track state. It provides methods for event dispatch and state management.
func FromContext ¶
FromContext retrieves a state machine instance from a context. Returns the instance and a boolean indicating whether it was found.
Example:
if sm, ok := hsm.FromContext(ctx); ok {
log.Printf("Current state: %s", sm.State())
}
func InstancesFromContext ¶
InstancesFromContext retrieves all state machine instances from a context. Returns a slice of instances and a boolean indicating whether any were found. This is useful when multiple state machines share a context and you need to access or iterate over all of them.
type Model ¶
type Model struct {
// TransitionMap provides fast lookup of transitions by state and event name
TransitionMap map[string]map[string][]*transition // stateQualifiedName -> eventName -> transitions
// DeferredMap provides fast lookup of deferred events by state
DeferredMap map[string]map[string]struct{} // stateQualifiedName -> Set<deferredEventNames>
// contains filtered or unexported fields
}
Model represents the complete state machine model definition. It contains the root state and maintains a namespace of all elements.
func Define ¶
func Define[T stringLike](name T, redefinableElements ...RedefinableElement) Model
Define creates a new state machine model with the given name and elements. The first argument can be either a string name or a RedefinableElement. Additional elements are added to the model in the order they are specified.
Example:
model := hsm.Define(
"traffic_light",
hsm.State("red"),
hsm.State("yellow"),
hsm.State("green"),
hsm.Initial("red")
)
func (*Model) Activities ¶
func (state *Model) Activities() []string
type OperationFunc ¶ added in v1.0.6
OperationFunc is a function type that performs an action on a state machine. Operations are used for state entry/exit behaviors, transition effects, and activity functions. They receive the current context, state machine instance, and the triggering event.
type RedefinableElement ¶
RedefinableElement is a function type that modifies a Model by adding or updating elements. It's used to build the state machine structure in a declarative way.
func Activity ¶
func Activity[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
Activity defines a long-running action that is executed while in a state. The activity is started after the entry action and stopped before the exit action.
Example:
hsm.Activity(func(ctx context.Context, hsm *MyHSM, event Event) {
for {
select {
case <-ctx.Done():
return
case <-time.After(time.Second):
log.Println("Activity tick")
}
}
})
func After ¶
func After[T Instance](expr func(ctx context.Context, hsm T, event Event) time.Duration) RedefinableElement
After creates a time-based transition that occurs after a specified duration. The duration can be dynamically computed based on the state machine's context.
Example:
hsm.Transition(
hsm.After(func(ctx context.Context, hsm *MyHSM, event Event) time.Duration {
return time.Second * 30
}),
hsm.Source("active"),
hsm.Target("timeout")
)
func At ¶ added in v1.1.0
func At[T Instance](expr func(ctx context.Context, hsm T, event Event) time.Time) RedefinableElement
At creates a time-based transition that occurs at a specific timestamp. The timestamp can be dynamically computed based on the state machine's context.
Example:
hsm.Transition(
hsm.At(func(ctx context.Context, hsm *MyHSM, event Event) time.Time {
return time.Now().Add(time.Minute)
}),
hsm.Source("active"),
hsm.Target("timeout")
)
func Attribute ¶ added in v1.0.3
func Attribute[T stringLike](name T, maybeDefault ...any) RedefinableElement
Attribute declares a model-level attribute with an optional default value. Attributes can be observed via OnSet("name") transitions and updated at runtime via Set / Instance.Set.
func Choice ¶
func Choice[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
Choice creates a pseudo-state that enables dynamic branching based on guard conditions. The first transition with a satisfied guard condition is taken.
Example:
hsm.Choice(
hsm.Transition(
hsm.Target("approved"),
hsm.Guard(func(ctx context.Context, hsm *MyHSM, event Event) bool {
return hsm.score > 700
})
),
hsm.Transition(
hsm.Target("rejected")
)
)
func DeepHistory ¶ added in v1.0.3
func DeepHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
DeepHistory creates a deep history pseudostate within a composite state. If no history is available, any transitions defined on this pseudostate are used; otherwise the parent state's initial is used.
func Defer ¶
func Defer[T interface {
string | *Event | Event
}](events ...T) RedefinableElement
Defer schedules events to be processed after the current state is exited.
Example:
hsm.Defer(hsm.Event{Name: "event_name"})
func Effect ¶
func Effect[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
Effect defines an action to be executed during a transition. The effect function is called after exiting the source state and before entering the target state.
Example:
hsm.Effect(func(ctx context.Context, hsm *MyHSM, event Event) {
log.Printf("Transitioning with event: %s", event.Name)
})
func Entry ¶
func Entry[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
Entry defines an action to be executed when entering a state. The entry action is executed before any internal activities are started.
Example:
hsm.Entry(func(ctx context.Context, hsm *MyHSM, event Event) {
log.Printf("Entering state with event: %s", event.Name)
})
func Every ¶
func Every[T Instance](expr func(ctx context.Context, hsm T, event Event) time.Duration) RedefinableElement
Every schedules events to be processed on an interval.
Example:
hsm.Every(func(ctx context.Context, hsm T, event Event) time.Duration {
return time.Second * 30
})
func Exit ¶
func Exit[T Instance](funcs ...func(ctx context.Context, hsm T, event Event)) RedefinableElement
Exit defines an action to be executed when exiting a state. The exit action is executed after any internal activities are stopped.
Example:
hsm.Exit(func(ctx context.Context, hsm *MyHSM, event Event) {
log.Printf("Exiting state with event: %s", event.Name)
})
func Final ¶
func Final[T stringLike](name T) RedefinableElement
Final creates a final state that represents the completion of a composite state or the entire state machine. When a final state is entered, a completion event is generated.
Example:
hsm.State("process",
hsm.State("working"),
hsm.Final("done"),
hsm.Transition(
hsm.Source("working"),
hsm.Target("done")
)
)
func Guard ¶
Guard defines a condition that must be true for a transition to be taken. If multiple transitions are possible, the first one with a satisfied guard is chosen.
Example:
hsm.Guard(func(ctx context.Context, hsm *MyHSM, event Event) bool {
return hsm.counter > 10
})
func Initial ¶
func Initial(partialElements ...RedefinableElement) RedefinableElement
Initial defines the initial state for a composite state or the entire state machine. When a composite state is entered, its initial state is automatically entered.
Example:
hsm.State("operational",
hsm.State("idle"),
hsm.State("running"),
hsm.Initial("idle")
)
func On ¶
func On[T interface{ *Event | Event }](events ...T) RedefinableElement
On defines the events that can cause a transition. Multiple events can be specified for a single transition.
Example:
hsm.Transition(
hsm.On("start", "resume"),
hsm.Source("idle"),
hsm.Target("running")
)
func OnCall ¶ added in v1.0.3
func OnCall[T stringLike](name T) RedefinableElement
OnCall creates a trigger for Call() invocations of the named operation.
func OnSet ¶ added in v1.0.3
func OnSet[T stringLike](name T) RedefinableElement
OnSet creates an attribute-change trigger for the given attribute name. It is the attribute-based equivalent of On(...) and is driven by Set.
func Operation ¶
func Operation[T stringLike](name T, fn any) RedefinableElement
Operation declares a named callable for Call()/OnCall(). Supported callables include function values and method expressions.
func ShallowHistory ¶ added in v1.0.3
func ShallowHistory[T redefinableOrString](elementOrName T, partialElements ...RedefinableElement) RedefinableElement
ShallowHistory creates a shallow history pseudostate within a composite state. If no history is available, any transitions defined on this pseudostate are used; otherwise the parent state's initial is used.
func Source ¶
func Source[T redefinableOrString](nameOrPartialElement T) RedefinableElement
Source specifies the source state of a transition. It can be used within a Transition definition.
Example:
hsm.Transition(
hsm.Source("idle"),
hsm.Target("running")
)
func State ¶
func State[T stringLike](name T, partialElements ...RedefinableElement) RedefinableElement
State creates a new state element with the given name and optional child elements. States can have entry/exit actions, activities, and transitions.
Example:
hsm.State("active",
hsm.Entry(func(ctx context.Context, hsm *MyHSM, event Event) {
log.Println("Entering active state")
}),
hsm.Activity(func(ctx context.Context, hsm *MyHSM, event Event) {
// Long-running activity
}),
hsm.Exit(func(ctx context.Context, hsm *MyHSM, event Event) {
log.Println("Exiting active state")
})
)
func Target ¶
func Target[T redefinableOrString](nameOrPartialElement T) RedefinableElement
Target specifies the target state of a transition. It can be used within a Transition definition.
Example:
hsm.Transition(
hsm.Source("idle"),
hsm.Target("running")
)
func Transition ¶
func Transition[T redefinableOrString](nameOrPartialElement T, partialElements ...RedefinableElement) RedefinableElement
Transition creates a new transition between states. Transitions can have triggers, guards, and effects.
Example:
hsm.Transition(
hsm.Trigger("submit"),
hsm.Source("draft"),
hsm.Target("review"),
hsm.Guard(func(ctx context.Context, hsm *MyHSM, event Event) bool {
return hsm.IsValid()
}),
hsm.Effect(func(ctx context.Context, hsm *MyHSM, event Event) {
log.Println("Transitioning from draft to review")
})
)
type Snapshot ¶
type Snapshot struct {
ID string
QualifiedName string
State string
Attributes map[string]any
QueueLen int
Events []EventDetail
}
func TakeSnapshot ¶
TakeSnapshot captures the current state of a state machine instance. The returned Snapshot contains the ID, qualified name, current state, data, and other attributes representing the instance at this moment. Useful for debugging, logging, or persisting state machine state.