Acts-As-State-Machine for Opal
Allows the Acts As State Machine (aasm) gem to be used with the Opal Ruby Transpiler. Its also ready to work right along side react.rb UI components. For detailed documentation on Acts As State Machine, refer the to AASM github page.
Installation
Add this line to your application's Gemfile:
gem 'opal-aasm'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install opal-aasm
Usage
class StateMachine
include Opal::StateMachine
state_machine_options :state_name => :component_state, :whiny_transitions => true
state :cleaning
state :sleeping, :initial => true
state :running
event(:run, after: -> () {puts "started running!!!!!!"}) do
transitions :from => :sleeping, :to => :running
end
event(:clean, error: -> () {puts "don't clean now!!!!!!!"}) do
transitions :from => :running, :to => :cleaning
end
event :sleep do
transitions :from => [:running, :cleaning], :to => :sleeping
end
# AASM will automatically define methods may_run?, run!, may_sleep?, sleep! etc
# to access these from the javascript console you would type
# machine = Opal.StateMachine.$new()
# machine["$may_run?"]()
# machine["$run"]()
# machine["$component_state"]()
end
Note that you do not need to wrap the state and event directives with the normal aasm do ... end
, but you
may still do so if desired. If you have a name conflict with state
or event
simply do the include of Opal::StateMachine after you define your state or event methods, and use the normal aasm
dsl wrapper.
To send options to AASM use the state_machine_options
directive as shown above.
Opal-aasm will define a method called current_state
that can be used to get the current state. You may override
the method name by using the state_name
option in the state_machine_options
directive as shown above.
Using with React.rb
The opal-aasm gem is "React" aware. Adding a state machine to a react component gives a very easy and powerful way to manage component state. For example consider turning the above into a react component:
class StateMachine
include React::Component
def render
div do
span { "current state: #{component_state}"}
button {"run" }.on(:click) {run!} if may_run?
button {"sleep"}.on(:click) {sleep!} if may_sleep?
button {"clean"}.on(:click) {clean!} # we will check this in the state call back
end
end
end
When both React::Component
and Opal::StateMachine
are included in the same class a hidden react state is updated whenever there is a state transition. The rest is handled by the magic of React.
Summary of additional features
The opal-aasm gem is intended to be upwards compatible with the standard AASM. The following are the additional features added by opal-aasm.
- No need to wrap
state
andevent
directives in an aasm block. - AASM options may be provided using the
state_machine_options
directive. - The
current_state
method may be used to access the current state. The name can be changed using thestate_name
option. - Will persist the current state as a react state variable if the
React::Component
mixin is present in the same class.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake rspec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/catprintlabs/opal-aasm. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.