opal-aasm 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ before_install: gem install bundler -v 1.10.2
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in opal-aasm.gemspec
4
+ gemspec
5
+ gem 'opal-react', path: "../react.rb"
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Mitch VanDuyn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,111 @@
1
+ # Acts-As-State-Machine for Opal
2
+
3
+ Allows the [Acts As State Machine (aasm)](https://github.com/aasm/aasm) gem to be used with the [Opal Ruby Transpiler](http://opalrb.org/). Its also ready to work right along side [react.rb](https://github.com/zetachang/react.rb) UI components. For detailed documentation on Acts As State Machine, refer the to [AASM](https://github.com/aasm/aasm) github page.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'opal-aasm'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install opal-aasm
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ class StateMachine
25
+
26
+ include Opal::StateMachine
27
+
28
+ state_machine_options :state_name => :component_state, :whiny_transitions => true
29
+
30
+ state :cleaning
31
+ state :sleeping, :initial => true
32
+ state :running
33
+
34
+ event(:run, after: -> () {puts "started running!!!!!!"}) do
35
+ transitions :from => :sleeping, :to => :running
36
+ end
37
+
38
+ event(:clean, error: -> () {puts "don't clean now!!!!!!!"}) do
39
+ transitions :from => :running, :to => :cleaning
40
+ end
41
+
42
+ event :sleep do
43
+ transitions :from => [:running, :cleaning], :to => :sleeping
44
+ end
45
+
46
+ # AASM will automatically define methods may_run?, run!, may_sleep?, sleep! etc
47
+
48
+ # to access these from the javascript console you would type
49
+ # machine = Opal.StateMachine.$new()
50
+ # machine["$may_run?"]()
51
+ # machine["$run"]()
52
+ # machine["$component_state"]()
53
+
54
+ end
55
+ ```
56
+
57
+ Note that you do not need to wrap the state and event directives with the normal `aasm do ... end`, but you
58
+ 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.
59
+
60
+ To send options to AASM use the `state_machine_options` directive as shown above.
61
+
62
+ Opal-aasm will define a method called `current_state` that can be used to get the current state. You may override
63
+ the method name by using the `state_name` option in the `state_machine_options` directive as shown above.
64
+
65
+ ## Using with [React.rb](https://github.com/zetachang/react.rb)
66
+
67
+ 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:
68
+
69
+ ```ruby
70
+ class StateMachine
71
+
72
+ include React::Component
73
+
74
+ def render
75
+ div do
76
+ span { "current state: #{component_state}"}
77
+ button {"run" }.on(:click) {run!} if may_run?
78
+ button {"sleep"}.on(:click) {sleep!} if may_sleep?
79
+ button {"clean"}.on(:click) {clean!} # we will check this in the state call back
80
+ end
81
+ end
82
+
83
+ end
84
+ ```
85
+
86
+ 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.
87
+
88
+ ## Summary of additional features
89
+
90
+ The opal-aasm gem is intended to be upwards compatible with the standard AASM. The following are the additional features added by opal-aasm.
91
+
92
+ * No need to wrap `state` and `event` directives in an aasm block.
93
+ * AASM options may be provided using the `state_machine_options` directive.
94
+ * The `current_state` method may be used to access the current state. The name can be changed using the `state_name` option.
95
+ * Will persist the current state as a react state variable if the `React::Component` mixin is present in the same class.
96
+
97
+ ## Development
98
+
99
+ 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.
100
+
101
+ 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](https://rubygems.org).
102
+
103
+ ## Contributing
104
+
105
+ 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](contributor-covenant.org) code of conduct.
106
+
107
+
108
+ ## License
109
+
110
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
111
+
@@ -0,0 +1,16 @@
1
+ #require "bundler/gem_tasks"
2
+ #require "rspec/core/rake_task"
3
+
4
+ #RSpec::Core::RakeTask.new(:spec)
5
+
6
+ #task :default => :spec
7
+ # Rakefile
8
+ require 'opal/rspec/rake_task'
9
+ require 'bundler'
10
+ Bundler.require
11
+
12
+ # Add our opal/ directory to the load path
13
+ Opal.append_path File.expand_path('../lib', __FILE__)
14
+
15
+
16
+ Opal::RSpec::RakeTask.new(:default)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "opal/aasm"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,12 @@
1
+ if RUBY_ENGINE == 'opal'
2
+ require_relative 'opal/aasm/version.rb'
3
+ require_relative 'opal/aasm.rb'
4
+ require_relative 'opal-aasm.rb'
5
+ else
6
+ require 'opal'
7
+ require 'opal-jquery'
8
+ require 'opal-react'
9
+ Opal.use_gem 'aasm'
10
+ Opal.use_gem 'react-source'
11
+ Opal.append_path File.expand_path('..', __FILE__).untaint
12
+ end
@@ -0,0 +1,160 @@
1
+ require "opal/aasm/version"
2
+ require "aasm"
3
+ require "aasm/persistence/plain_persistence"
4
+
5
+ module Opal
6
+ module StateMachine
7
+
8
+ # the following method adds the hidden react state variable to React::Component, by adding our
9
+ # own self.included method to React::Component.
10
+ # Because we want to allow the modules to be required and included in any order extend_react_component
11
+ # will be called twice. Once when Opal::StateMachine is included, and once when this file is required.
12
+ # The instance variable @original_included_method_for_state_machine protects us from infinite recursion.
13
+
14
+ # 1 we are required first, we are included first
15
+ # 2 we are required first, we are included second
16
+ # 3 we are required second, we are included first
17
+ # 4 we are required second, we are included second
18
+ # 5 we are required, but they are not
19
+
20
+ def self.extend_react_component(where, klass = nil)
21
+ return if klass and klass.respond_to? :aasm_event_fired # case 4 already handled when we were required.
22
+ if klass and klass.respond_to? :define_state
23
+ # case 2
24
+ klass.define_state :protected_current_react_state_var
25
+ klass.define_method :aasm_event_fired do |event, from, to|
26
+ protected_current_react_state_var! to.to_s if from != to
27
+ end
28
+ elsif defined? React::Component
29
+ # case 3 + 4 (second call from include will be ignored)
30
+ # case 1 (first call from require will be ignored)
31
+ React::Component.module_eval do
32
+ # alias_method does not work on :included so we do it the hard way
33
+ unless @original_included_method_for_state_machine
34
+ @original_included_method_for_state_machine = self.method(:included)
35
+ def self.included(base)
36
+ @original_included_method_for_state_machine.call(base)
37
+ base.define_state :protected_current_react_state_var
38
+ base.define_method :aasm_event_fired do |event, from, to|
39
+ protected_current_react_state_var! to.to_s if from != to
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def current_state
48
+ protected_current_react_state_var if respond_to? :render
49
+ aasm.current_state.to_s
50
+ end
51
+
52
+ module AASMAPI
53
+
54
+ # add the event and state methods to the class so we don't have to wrap with the aasm block
55
+
56
+ ["event", "state"].each do |method_name|
57
+ define_method(method_name) do |*args, &block|
58
+ aasm do
59
+ send(method_name, *args, &block)
60
+ end
61
+ end
62
+ end
63
+
64
+ # add the state_machine_options directive and the new :state_name option
65
+
66
+ def state_machine_options(opts={})
67
+ define_method(opts.delete(:state_name)) do
68
+ protected_current_react_state_var if respond_to? :render
69
+ aasm.current_state.to_s
70
+ end if opts[:state_name]
71
+ aasm opts
72
+ end
73
+
74
+ end
75
+
76
+ def self.included(base)
77
+
78
+ Opal::StateMachine.extend_react_component("StateMachine included", base)
79
+
80
+ base.include AASM
81
+ base.extend AASMAPI
82
+
83
+ end
84
+
85
+ end
86
+ end
87
+
88
+ # Work around a couple of incompatibilities with Opal and AASM
89
+
90
+ module AASM
91
+
92
+ # redefine because of opal breaks when doing a super in this case
93
+ def self.included(base)
94
+ base.extend AASM::ClassMethods
95
+ AASM::StateMachine[base] ||= AASM::StateMachine.new
96
+ AASM::Persistence.load_persistence(base)
97
+ super rescue nil #<--------------------------------added because of bug in opal
98
+ end
99
+
100
+ module Persistence
101
+
102
+ # override normal AASM load_persisentence method as it uses various features not supported by opal
103
+
104
+ def self.load_persistence(base)
105
+ base.send(:include, AASM::Persistence::PlainPersistence)
106
+ end
107
+
108
+ end
109
+
110
+ # redefine the initialize method because it was was doing a very expensive
111
+ # (for Opal) class_eval with a string (instead of a block). While we are redefining this
112
+ # the unnecessary options have been removed.
113
+
114
+ class Base
115
+
116
+ attr_reader :state_machine
117
+
118
+ def initialize(klass, options={}, &block)
119
+ @klass = klass
120
+ @state_machine = AASM::StateMachine[@klass]
121
+ @options = options
122
+
123
+ # let's cry if the transition is invalid
124
+ configure :whiny_transitions, true
125
+
126
+ end
127
+ end
128
+ end
129
+
130
+ Opal::StateMachine.extend_react_component("StateMachine file loaded")
131
+
132
+ # Last but not least add catch/throw to Opal as these are currently missing (as of version 8.beta)
133
+ # There is a PR to bring these into Opal properly.
134
+
135
+ class Object
136
+
137
+ def catch(sym)
138
+ yield
139
+ rescue CatchThrow => e
140
+ return e.arg if e.sym == sym
141
+ raise e
142
+ end
143
+
144
+ def throw(*args)
145
+ raise CatchThrow.new(args)
146
+ end
147
+
148
+ protected
149
+
150
+ class CatchThrow < Exception
151
+ attr_reader :sym
152
+ attr_reader :arg
153
+ def initialize(args)
154
+ @sym = args[0]
155
+ @arg = args[1] if args.count > 1
156
+ end
157
+ end
158
+
159
+ end
160
+
@@ -0,0 +1,5 @@
1
+ module Opal
2
+ module StateMachine
3
+ VERSION = "0.7.0"
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'opal/aasm/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "opal-aasm"
8
+ spec.version = Opal::StateMachine::VERSION
9
+ spec.authors = ["Mitch VanDuyn"]
10
+ spec.email = ["mitch@catprint.com"]
11
+
12
+ spec.summary = "Acts-As-State-Machine for Opal"
13
+ spec.description = <<DESCRIPTION
14
+ Allows the Acts As State Machine (aasm) gem to be used with the Opal Ruby Transpiler.
15
+ Its also ready to work right along side react.rb UI components. For detailed documentation on Acts As State Machine,
16
+ refer the to AASM github page at https://github.com/aasm/aasm.
17
+ DESCRIPTION
18
+ spec.homepage = "https://github.com/catprintlabs/opal-aasm"
19
+ spec.license = "MIT"
20
+
21
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.10"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "opal-rspec"
29
+ spec.add_development_dependency "opal-jquery"
30
+ spec.add_development_dependency 'react-source', '~> 0.12'
31
+ spec.add_development_dependency 'opal-react'
32
+ spec.add_runtime_dependency 'opal'
33
+ spec.add_runtime_dependency 'aasm'
34
+
35
+ end
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opal-aasm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mitch VanDuyn
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-06-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.10'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.10'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '10.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '10.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: opal-rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: opal-jquery
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: react-source
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.12'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.12'
94
+ - !ruby/object:Gem::Dependency
95
+ name: opal-react
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: opal
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: aasm
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description: ! "Allows the Acts As State Machine (aasm) gem to be used with the Opal
143
+ Ruby Transpiler.\nIts also ready to work right along side react.rb UI components.
144
+ \ For detailed documentation on Acts As State Machine, \nrefer the to AASM github
145
+ page at https://github.com/aasm/aasm.\n"
146
+ email:
147
+ - mitch@catprint.com
148
+ executables: []
149
+ extensions: []
150
+ extra_rdoc_files: []
151
+ files:
152
+ - .gitignore
153
+ - .rspec
154
+ - .travis.yml
155
+ - CODE_OF_CONDUCT.md
156
+ - Gemfile
157
+ - LICENSE.txt
158
+ - README.md
159
+ - Rakefile
160
+ - bin/console
161
+ - bin/setup
162
+ - lib/opal-aasm.rb
163
+ - lib/opal/aasm.rb
164
+ - lib/opal/aasm/version.rb
165
+ - opal-aasm.gemspec
166
+ homepage: https://github.com/catprintlabs/opal-aasm
167
+ licenses:
168
+ - MIT
169
+ post_install_message:
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ! '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ required_rubygems_version: !ruby/object:Gem::Requirement
180
+ none: false
181
+ requirements:
182
+ - - ! '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 1.8.24
188
+ signing_key:
189
+ specification_version: 3
190
+ summary: Acts-As-State-Machine for Opal
191
+ test_files: []