This reference summarizes the exported API. Start with Getting started for a runnable flow and use the topic guides for behavioral details.
type Arc struct {
Place string
Weight int
}
func NewArc(place string, weight int) (Arc, error)Describes a weighted input or output connection. Place names must be non-empty and weights must be positive.
func NewTransition(name string, from, to []Arc) (*Transition, error)
func (t *Transition) Name() string
func (t *Transition) From() []Arc
func (t *Transition) To() []ArcTransitions own defensive copies of their arcs. From and To also return copies.
func NewDefinition(
places []string,
transitions []*Transition,
options ...DefinitionOption,
) (*Definition, error)
func (d *Definition) Places() []string
func (d *Definition) InitialPlaces() []string
func (d *Definition) Transitions() []*Transition
func (d *Definition) MetadataStore() MetadataStoreAn immutable, validated workflow graph.
Definition options:
func WithInitialPlaces(places ...string) DefinitionOption
func WithMetadataStore(store MetadataStore) DefinitionOptionfunc NewDefinitionBuilder() *DefinitionBuilder
func (b *DefinitionBuilder) AddPlaces(places ...string) error
func (b *DefinitionBuilder) AddTransition(transition *Transition) error
func (b *DefinitionBuilder) SetInitialPlaces(places ...string) error
func (b *DefinitionBuilder) SetMetadataStore(store MetadataStore)
func (b *DefinitionBuilder) Build() (*Definition, error)Collects graph configuration incrementally and delegates final validation and copying to NewDefinition.
func NewMarking(places map[string]int) (*Marking, error)
func (m *Marking) Places() map[string]int
func (m *Marking) Context() map[string]any
func (m *Marking) SetContext(context map[string]any) error
func (m *Marking) Has(place string) bool
func (m *Marking) Mark(place string, tokens int) error
func (m *Marking) Unmark(place string, tokens int) errorStores positive token counts and copied operation context.
type WorkflowInterface interface {
Name() string
Definition() *Definition
GetMarking(any) (*Marking, error)
Can(any, string) (bool, error)
TransitionBlockers(any, string) (*TransitionBlockerList, error)
Apply(any, string, map[string]any) (*Marking, error)
EnabledTransitions(any) ([]*Transition, error)
EnabledTransition(any, string) (*Transition, error)
}The shared boundary implemented by workflows, state machines, and trace wrappers.
func NewWorkflow(definition *Definition, options ...WorkflowOption) (*Workflow, error)Supports multiple active places, multiple arcs, weighted tokens, splits, and joins. It implements every method in WorkflowInterface.
type StateMachine struct{ *Workflow }
func NewStateMachine(definition *Definition, options ...WorkflowOption) (*StateMachine, error)Embeds Workflow and enforces at most one initial place, at most one input and output arc per transition, and unit weights.
func WithName(name string) WorkflowOption
func WithDispatcher(dispatcher Dispatcher) WorkflowOption
func WithMarkingStore(store MarkingStore) WorkflowOption
func WithEventsToDispatch(events ...string) WorkflowOptionOptions configure identity, events, state persistence, and lifecycle-event filtering.
type TransitionBlocker struct {
Message string
Code string
}
func NewTransitionBlockerList(blockers ...TransitionBlocker) *TransitionBlockerList
func (l *TransitionBlockerList) Add(blocker TransitionBlocker)
func (l *TransitionBlockerList) Empty() bool
func (l *TransitionBlockerList) Len() int
func (l *TransitionBlockerList) All() []TransitionBlockerAll returns blockers in insertion order as a defensive slice.
Built-in codes:
const BlockedByMarkingCode = "workflow_marking"
const GuardBlockedCode = "workflow_guard"type MarkingStore interface {
GetMarking(any) (*Marking, error)
SetMarking(any, *Marking, map[string]any) error
}func NewSubjectMarkingStore() *SubjectMarkingStoreDefault multi-place store. It expects WorkflowMarking() map[string]int and SetWorkflowMarking(map[string]int, map[string]any) on the subject.
func NewSingleStateMarkingStore() *SingleStateMarkingStoreDefault state-machine store. It expects WorkflowState() string and SetWorkflowState(string, map[string]any).
func NewMethodMarkingStore(singleState bool, property string) *MethodMarkingStoreReflection-backed property store. For property status, it resolves GetStatus/SetStatus methods or an exported Status field. State machines use string values; workflows use map[string]int. An empty property selects marking.
func NewAccessorMarkingStore(
get func(any) (map[string]int, error),
set func(any, map[string]int, map[string]any) error,
) *AccessorMarkingStoreUses caller-supplied multi-place getter and setter functions.
func NewSingleStateAccessorStore(
get func(any) (string, error),
set func(any, string, map[string]any) error,
) *SingleStateAccessorStoreUses caller-supplied single-state getter and setter functions.
func NewRegistry() *Registry
func NewRegistryWithLimits(ResourceLimits) *Registry
func (r *Registry) Add(workflow WorkflowInterface, strategy SupportStrategy) error
func (r *Registry) Len() int
func (r *Registry) Get(subject any, name string) (WorkflowInterface, error)
func (r *Registry) Has(subject any, name string) bool
func (r *Registry) All(subject any) []WorkflowInterfaceGet requires exactly one supported match. Named lookup uses a name index; an empty name scans all registered entries.
Support strategy APIs:
type SupportStrategy interface {
Supports(WorkflowInterface, any) bool
}
type SupportStrategyFunc func(WorkflowInterface, any) bool
func TypeSupportStrategy[T any]() SupportStrategyfunc NewConfigurationBindings() *ConfigurationBindings
func (b *ConfigurationBindings) RegisterSupport(string, SupportStrategy) error
func (b *ConfigurationBindings) RegisterMarkingStore(string, MarkingStore) error
func (b *ConfigurationBindings) RegisterPlaceSet(string, ...string) error
func (b *ConfigurationBindings) RegisterDefinitionValidator(string, DefinitionValidator) error
func (b *ConfigurationBindings) SetAuditLogger(*log.Logger) error
type DefinitionValidator interface {
Validate(*Definition, string) error
}
func NewYAMLLoader(*Registry, *ConfigurationBindings) *YAMLLoader
func NewYAMLLoaderWithLimits(*Registry, *ConfigurationBindings, ResourceLimits) *YAMLLoader
func (l *YAMLLoader) Load(path string) error
func (l *YAMLLoader) Decode(data []byte) error
func (l *YAMLLoader) Registry() *Registry
func (l *YAMLLoader) Dispatcher() *EventDispatcherSupport, service, and validator names are explicitly bound to Go behavior. Method marking stores additionally resolve their configured property through accessor methods or an exported field. YAML maps retain source order, weighted arcs are preserved for workflows, unknown fields are rejected, and a rejected document does not add workflows to the registry. See YAML configuration for the complete schema.
type Dispatcher = contracts.Dispatcher
type EventDispatcher = eventdispatcher.EventDispatcher
type Listener = eventdispatcher.Listener
type ListenerHandle = eventdispatcher.ListenerID
type SubscriberHandle = eventdispatcher.SubscriberID
type EventSubscription = eventdispatcher.Subscription
type EventSubscriber = eventdispatcher.Subscriber
type RegisteredListener = eventdispatcher.RegisteredListener
type GenericEvent = eventdispatcher.GenericEvent
type NamedEvent = contracts.NamedEvent
func NewEventDispatcher() *eventdispatcher.EventDispatcher
func NewImmutableDispatcher(eventdispatcher.Dispatcher) eventdispatcher.Dispatcher
func NewGenericEvent(subject any, arguments map[string]any) *eventdispatcher.GenericEventThese are integrations and aliases of the standalone dispatcher libraries; workflow does not maintain another listener implementation.
const (
EventAnnounce = "workflow.announce"
EventCompleted = "workflow.completed"
EventEntered = "workflow.entered"
EventEnter = "workflow.enter"
EventGuard = "workflow.guard"
EventLeave = "workflow.leave"
EventTransition = "workflow.transition"
)
func WorkflowEventName(kind, workflowName, node string) (string, error)
func NewListenerBinding(kind, workflowName, node string) (ListenerBinding, error)ListenerBinding contains the resolved Event name.
type WorkflowEvent interface {
Subject() any
Marking() *Marking
Transition() *Transition
WorkflowName() string
Context() map[string]any
SetContext(map[string]any)
}Concrete types are AnnounceEvent, CompletedEvent, EnteredEvent, EnterEvent, LeaveEvent, and TransitionEvent.
func NewGuardEvent(
subject any,
marking *Marking,
transition *Transition,
workflow WorkflowInterface,
context map[string]any,
) *GuardEvent
func (e *GuardEvent) Blocked() bool
func (e *GuardEvent) PropagationStopped() bool
func (e *GuardEvent) AddBlocker(blocker TransitionBlocker)
func (e *GuardEvent) Blockers() *TransitionBlockerList
func (e *GuardEvent) SetBlocked(blocked bool, message string)GuardEvent also implements WorkflowEvent.
type GuardContext struct {
Subject any
Marking *Marking
Transition *Transition
Workflow WorkflowInterface
Context map[string]any
}
type GuardRule struct {
Transition *Transition
Evaluate func(GuardContext) (bool, error)
}
func NewGuardRuleListener(rules map[string][]GuardRule) *GuardRuleListener
func (l *GuardRuleListener) OnTransition(event *GuardEvent, eventName string) errorPer-apply context constants:
const (
DisableLeaveEvent = "disable_leave_event"
DisableTransitionEvent = "disable_transition_event"
DisableEnterEvent = "disable_enter_event"
DisableEnteredEvent = "disable_entered_event"
DisableCompletedEvent = "disable_completed_event"
DisableAnnounceEvent = "disable_announce_event"
)func NewAuditTrailSubscriber(logger *log.Logger) *AuditTrailSubscriber
func (s *AuditTrailSubscriber) Subscriptions() []EventSubscriptionLogs leave, transition, and enter activity.
type Metadata map[string]any
type MetadataStore interface {
WorkflowMetadata() Metadata
PlaceMetadata(string) Metadata
TransitionMetadata(*Transition) Metadata
WorkflowValue(string) (any, bool)
PlaceValue(string, string) (any, bool)
TransitionValue(*Transition, string) (any, bool)
}In-memory implementation:
func NewInMemoryMetadataStore(
workflow Metadata,
places map[string]Metadata,
transitions map[*Transition]Metadata,
) *InMemoryMetadataStoreIt implements every MetadataStore method and uses defensive copies for metadata maps.
type TransitionRendering int
const (
WorkflowTransitions TransitionRendering = iota
StateMachineTransitions
)
type DumpOptions struct {
WithMetadata bool
Label string
Title string
IncludeListeners bool
}
func SupportedDumpFormats() []string
func DumpWorkflow(definition *Definition, format string, options DumpOptions) (string, error)Concrete dumpers:
func NewMermaidDumper(rendering TransitionRendering) *MermaidDumper
func (d *MermaidDumper) Dump(*Definition, *Marking, any) (string, error)
func NewGraphvizDumper() *GraphvizDumper
func NewStateMachineGraphvizDumper() *GraphvizDumper
func (d *GraphvizDumper) Dump(*Definition, *Marking, any) (string, error)
func NewPlantUMLDumper(rendering TransitionRendering) *PlantUMLDumper
func (d *PlantUMLDumper) Dump(*Definition, *Marking, any) (string, error)The final argument accepts nil, DumpOptions, or *DumpOptions.
type WorkflowCall struct {
Method string
Duration time.Duration
Return any
Err error
}
func NewTraceableWorkflow(inner WorkflowInterface) *TraceableWorkflow
func NewTraceableWorkflowWithCapacity(inner WorkflowInterface, capacity int) (*TraceableWorkflow, error)
func (t *TraceableWorkflow) Calls() []WorkflowCall
func (t *TraceableWorkflow) Capacity() int
func (t *TraceableWorkflow) DroppedCalls() uint64
func (t *TraceableWorkflow) Reset()TraceableWorkflow implements WorkflowInterface and records method duration, return value, and error in a bounded chronological ring containing the newest calls. The default capacity is 128 calls.
type DiagnosticsItem struct {
Dump string
Listeners map[string][]RegisteredListener
}
func NewDiagnosticsCollector(
workflows []WorkflowInterface,
dispatcher *EventDispatcher,
) *DiagnosticsCollector
func (c *DiagnosticsCollector) Collect() (map[string]DiagnosticsItem, error)Collects Mermaid definitions and workflow-specific listener snapshots.
func NewWorkflowValidator(singleState bool) *WorkflowValidator
func (v *WorkflowValidator) Validate(definition *Definition, name string) error
func NewStateMachineValidator() *StateMachineValidator
func (v *StateMachineValidator) Validate(definition *Definition, name string) errorWorkflow validation checks ambiguous duplicate-name variants. State-machine validation additionally checks initial-place count, input/output cardinality, and arc weights.
type UndefinedTransitionError struct {
Transition string
Workflow string
Context map[string]any
}Unwraps to ErrUndefinedTransition.
type NotEnabledTransitionError struct {
Transition string
Workflow WorkflowInterface
Subject any
Blockers *TransitionBlockerList
Context map[string]any
}Unwraps to ErrNotEnabledTransition.
All sentinel errors support errors.Is when wrapped:
| Error | Condition |
|---|---|
ErrEmptyPlace |
empty place name |
ErrInvalidWeight |
non-positive arc weight |
ErrEmptyTransitionName |
empty transition name |
ErrUnknownInitialPlace |
initial place is absent from the definition |
ErrPlaceNotMarked |
token removal from a missing place |
ErrNegativeTokens |
removal would make a token count negative |
ErrInvalidTokenCount |
non-positive marking token count |
ErrNoInitialPlace |
empty marking cannot be initialized |
ErrUnknownPlace |
a store returns a place outside the definition |
ErrUndefinedTransition |
transition name is not defined |
ErrNotEnabledTransition |
transition is defined but disabled |
ErrGuardEventCannotBeDisabled |
guard event appears in a block-list |
ErrMixedEventFilterModes |
allow-list and block-list are mixed |
ErrUnsupportedSubject |
marking store cannot handle the subject |
ErrMultipleStates |
single-state marking has invalid cardinality or weight |
ErrMultipleWorkflows |
registry selection is ambiguous |
ErrWorkflowNotFound |
registry has no supported match |
ErrDuplicateTransitionName |
same-name variants share an input place |
ErrInvalidStateMachineArc |
state-machine arc weight is not one |
ErrMultipleOutputs |
state-machine transition has several outputs |
ErrMultipleInputs |
state-machine transition has several inputs |
ErrWorkflowNameRequired |
node-specific event lacks workflow name |
ErrUnsupportedDumpFormat |
dump format is unknown |
ErrDispatcherRequired |
requested diagnostics require a dispatcher |