An auditable, type-safe workflow state machine library for MoonBit.
moon add Rz-coder8848/moon-fsmlet builder : @fsm.Builder[String, String, Int] = @fsm.Builder::new()
.transition_do("Draft", "Submit", "Review", fn(_s, _e, ctx) { ctx + 1 })
.transition_if_do(
"Review",
"Approve",
"Approved",
fn(_s, _e, ctx) { ctx >= 2 },
fn(_s, _e, ctx) { ctx + 10 },
)
let engine = builder.build("Draft", 1)
ignore(engine.try_send("Submit"))stateDiagram-v2
Draft --> Review.Pending : Submit [action]
Review.Pending --> Review.Approved : Approve [guard] [action]
Review.Pending --> Review.Rework : RequestChanges
Review.Pending --> Cancelled : Cancel
Review.Pending --> Review.Rejected : Reject
Review.Rework --> Review.Pending : Resubmit [action]
Review.Rework --> Cancelled : Cancel
Review.Rejected --> Error.Validation : Escalate
Review.Approved --> Closed : ArchivestateDiagram-v2
Created --> Paid : Pay [action]
Paid --> Packed : Pack [action]
Packed --> Shipped : Ship [guard] [action]
Shipped --> Delivered : Deliver
Paid --> Cancelled : Cancel
Packed --> Cancelled : Cancel
Shipped --> Returned : Return [action]moon run examples/approval_workflow
moon run examples/order_workflowmoon run benchmarksmoon version --all
moon fmt --check
moon info
moon check --deny-warn --target all
moon test --deny-warn --target all
powershell -ExecutionPolicy Bypass -File scripts/verify_acceptance.ps1 -SkipMooncakes
moon run benchmarks
moon publish --dry-runtype Callback[S, E, Ctx] = (S, E, Ctx) -> Unittype Guard[S, E, Ctx] = (S, E, Ctx) -> Booltype TransitionAction[S, E, Ctx] = (S, E, Ctx) -> Ctxpub(all) struct AuditRecord[S, E] {
from : S
to : S
event : E
success : Bool
error : TransitionError?
history_index : Int?
}pub(all) struct BatchReport[E] {
outcomes : Array[DispatchOutcome[E]]
successful : Int
rejected : Int
complete : Bool
}pub(all) struct BudgetReport[E] {
outcomes : Array[DispatchOutcome[E]]
successful : Int
rejected : Int
processed : Int
stopped : Bool
}pub(all) struct ContextManager[Ctx] {
inner : Ctx
}pub(all) struct Engine[S, E, Ctx] {
transitions : Map[S, Map[E, S]]
guards : Map[S, Map[E, (S, E, Ctx) -> Bool]]
actions : Map[S, Map[E, (S, E, Ctx) -> Ctx]]
on_enter : Map[S, (S, E, Ctx) -> Unit]
on_exit : Map[S, (S, E, Ctx) -> Unit]
history_entries : Array[TransitionRecord[S, E]]
audit_entries : Array[AuditRecord[S, E]]
metrics_value : ExecutionMetrics
current_state : S
context : Ctx
last_error_value : TransitionError?
build_error : TransitionError?
}fn[S, E, Ctx] Engine::restore(self : Engine[S, E, Ctx], snapshot : EngineSnapshot[S, E, Ctx]) -> Unitfn[S : Hash + Eq, E : Hash + Eq, Ctx] Engine::try_send_with_retry(self : Engine[S, E, Ctx], event : E, policy : RetryPolicy) -> RetryReport[E]pub(all) struct EngineConfig[S, E, Ctx] {
transitions : Array[Transition[S, E, Ctx]]
on_enter : Map[S, (S, E, Ctx) -> Unit]
on_exit : Map[S, (S, E, Ctx) -> Unit]
}pub(all) struct EngineOptions {
strict_mode : Bool
max_history : Int
}pub(all) struct EngineSnapshot[S, E, Ctx] {
state : S
context : Ctx
history_entries : Array[TransitionRecord[S, E]]
audit_entries : Array[AuditRecord[S, E]]
metrics : ExecutionMetrics
last_error : TransitionError?
}pub(all) struct ExecutionMetrics {
attempted : Int
successful : Int
rejected : Int
guard_rejected : Int
unknown_event : Int
no_outgoing_state : Int
duplicate_configuration : Int
invalid_configuration : Int
lifecycle_hooks : Int
} derive(Eq)pub(all) struct HistorySummary {
transitions : Int
guarded_transitions : Int
action_transitions : Int
distinct_states : Int
first_state : String?
last_state : String?
}pub(all) struct JournalAggregate {
tickets : Int
entries : Int
informational : Int
warnings : Int
errors : Int
critical : Int
unacknowledged : Int
}pub(all) struct JournalEntry {
sequence : Int
ticket_id : String
state : String
event : String
level : JournalLevel
message : String
acknowledged : Bool
}pub(all) struct JournalFilter {
ticket_id : String?
minimum_level : JournalLevel?
include_acknowledged : Bool
event_prefix : String?
}pub(all) struct RetryReport[E] {
attempts : Array[RetryAttempt[E]]
accepted : Bool
exhausted : Bool
final_error : TransitionError?
}pub(all) struct SlaEvaluation {
within_steps : Bool
within_escalations : Bool
breached : Bool
remaining_steps : Int
remaining_escalations : Int
}pub(all) struct TicketJournalSummary {
ticket_id : String
total_entries : Int
accepted_events : Int
warnings : Int
incidents : Int
critical : Int
unacknowledged : Int
last_state : String?
}pub(all) struct Transition[S, E, Ctx] {
from : S
to : S
event : E
guard_cond : (S, E, Ctx) -> Bool?
action : (S, E, Ctx) -> Ctx?
}pub(all) enum TransitionError {
NoTransitionsForCurrentState
EventNotHandledInCurrentState
GuardRejected
DuplicateTransitionDefinition
InvalidConfiguration
} derive(Eq)pub(all) struct TransitionRecord[S, E] {
from : S
event : E
to : S
used_guard : Bool
used_action : Bool
} derive(Eq)fn WorkflowJournal::append_audit(self : WorkflowJournal, ticket_id : String, audit : Array[AuditRecord[String, String]]) -> Intfn WorkflowJournal::critical(self : WorkflowJournal, ticket_id : String, state : String, event : String, message : String) -> Intfn WorkflowJournal::error(self : WorkflowJournal, ticket_id : String, state : String, event : String, message : String) -> Intfn WorkflowJournal::info(self : WorkflowJournal, ticket_id : String, state : String, event : String, message : String) -> Intfn WorkflowJournal::warning(self : WorkflowJournal, ticket_id : String, state : String, event : String, message : String) -> Intfn assert_invariant(cond : Bool, _msg : String) -> Unitfn[S : Eq, E : Eq, Ctx] duplicate_transition_entries(builder : Builder[S, E, Ctx]) -> Array[DuplicateTransition[S, E]]fn[S : Hash + Eq, E, Ctx] graph_summary(builder : Builder[S, E, Ctx], initial_state : S) -> GraphSummary[S]fn[S : Hash + Eq, E : Eq, Ctx] validate_report(builder : Builder[S, E, Ctx], initial_state : S) -> ValidationReport[S, E]An auditable, type-safe workflow state machine library for MoonBit.