Elixir Finite state machine

This package is inspired by ecto_fsm package

This package allows to use finite state machine pattern in elixir.

Install

def deps do
  [
    {:as_fsm, "~> 0.1.0"}
  ]
end

1. Usage

Define your FSM

defmodule OrderState do

  # define state, event and transition 
  use AsFsm,
    states: [:new, :processing, :cancelled, :delivered],
    events: [
      confirm: [
        name:     "Confirm",
        from:     [:new],
        to:       :processing,
        on_transition: fn(model, params) -> 
        # do something
        {:ok, model}
        end
      ], 
      deliver: [
        name:     "Deliver",
        from:     [:processing],
        to:       :delivered
      ], 
      cancel: [
        name:     "Cancel order",
        from:     [:new, :processing],
        to:       :cancelled,
        on_transition: &update_stock/2
      ]
    ]
    
    # define your callback function
    def update_stock(model, params)  do
      # your code
    end
end

list all state

#> OrderState.states()
#> [:new, :processing, :cancelled, :delivered]

list all event

#> OrderState.events()
#> [{:confirm, "Confirm"}, {:deliver, "Deliver"}, {:cancel, "Cancel Order"}]

Check if can accept event

#> model = %{status: :new}
#> OrderState.can?(model, :confirm)
#> true
#> OrderState.can?(model, :cancel)
#> true
#> OrderState.can?(model, :deliver)
#> false

Get accepted events All events that can used to trigger a transition

#> model = %{status: :new}
#> OrderState.accepted_events(model)
#> [{:confirm, "Confirm"}, {:cancel, "Cancel order"}]

Trigger an event

#> model = %{status: :new}
#> OrderState.confirm(model)
#> %{status: :processing}
#> # you can even pass data when trigger event
#> OrderState.confirm(model, %{message: "oke man"})

Dynamic trigger event

#> model = %{status: :new}
#> OrderState.trigger(model, :confirm)
#> %{status: :processing}
#> # you can even pass data when trigger event
#> OrderState.trigger(model, :confirm, %{message: "oke man"})

Options