hyper-react 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +11 -0
  4. data/Appraisals +10 -0
  5. data/CHANGELOG.md +31 -0
  6. data/Gemfile +2 -0
  7. data/README.md +7 -0
  8. data/gemfiles/opal_0.10_react_13.gemfile +4 -0
  9. data/gemfiles/opal_0.10_react_14.gemfile +4 -0
  10. data/gemfiles/opal_0.10_react_15.gemfile +4 -0
  11. data/gemfiles/opal_0.8_react_13.gemfile +4 -0
  12. data/gemfiles/opal_0.8_react_14.gemfile +4 -0
  13. data/gemfiles/opal_0.8_react_15.gemfile +4 -0
  14. data/gemfiles/opal_0.9_react_13.gemfile +4 -0
  15. data/gemfiles/opal_0.9_react_14.gemfile +4 -0
  16. data/gemfiles/opal_0.9_react_15.gemfile +4 -0
  17. data/gemfiles/opal_master_react_15.gemfile +18 -0
  18. data/hyper-react.gemspec +4 -0
  19. data/lib/hyper-react.rb +24 -4
  20. data/lib/rails-helpers/top_level_rails_component.rb +1 -1
  21. data/lib/react/api.rb +10 -0
  22. data/lib/react/component.rb +135 -106
  23. data/lib/react/component/base.rb +5 -1
  24. data/lib/react/component/class_methods.rb +12 -37
  25. data/lib/react/component/dsl_instance_methods.rb +0 -4
  26. data/lib/react/component/props_wrapper.rb +0 -5
  27. data/lib/react/component/should_component_update.rb +1 -5
  28. data/lib/react/component/tags.rb +7 -22
  29. data/lib/react/config.rb +5 -0
  30. data/lib/react/config/client.rb.erb +19 -0
  31. data/lib/react/config/server.rb +20 -0
  32. data/lib/react/element.rb +1 -0
  33. data/lib/react/native_library.rb +2 -7
  34. data/lib/react/react-source-browser.rb +3 -0
  35. data/lib/react/react-source-server.rb +3 -0
  36. data/lib/react/react-source.rb +12 -1
  37. data/lib/react/ref_callback.rb +31 -0
  38. data/lib/react/rendering_context.rb +9 -9
  39. data/lib/react/server.rb +23 -0
  40. data/lib/react/state_wrapper.rb +23 -0
  41. data/lib/react/test/matchers/render_html_matcher.rb +4 -2
  42. data/lib/react/top_level.rb +2 -0
  43. data/lib/reactive-ruby/component_loader.rb +2 -1
  44. data/lib/reactive-ruby/isomorphic_helpers.rb +10 -0
  45. data/lib/reactive-ruby/version.rb +1 -1
  46. data/lib/reactrb/auto-import.rb +2 -7
  47. data/spec/react/callbacks_spec.rb +8 -7
  48. data/spec/react/component_spec.rb +24 -13
  49. data/spec/react/dsl_spec.rb +12 -8
  50. data/spec/react/element_spec.rb +7 -7
  51. data/spec/react/native_library_spec.rb +25 -43
  52. data/spec/react/param_declaration_spec.rb +9 -0
  53. data/spec/react/react_spec.rb +0 -7
  54. data/spec/react/refs_callback_spec.rb +56 -0
  55. data/spec/react/server_spec.rb +25 -0
  56. data/spec/react/state_spec.rb +3 -3
  57. data/spec/react/top_level_component_spec.rb +1 -1
  58. data/spec/spec_helper.rb +31 -1
  59. metadata +72 -9
  60. data/lib/react/observable.rb +0 -29
  61. data/lib/react/state.rb +0 -191
  62. data/lib/sources/react-latest.js +0 -21169
  63. data/lib/sources/react-v13.js +0 -21645
  64. data/lib/sources/react-v14.js +0 -20821
  65. data/lib/sources/react-v15.js +0 -21170
@@ -66,7 +66,16 @@ describe 'the param macro', type: :component do
66
66
  end
67
67
  end
68
68
 
69
+ %x{
70
+ var log = [];
71
+ var org_warn_console = window.console.warn;
72
+ var org_error_console = window.console.error;
73
+ window.console.warn = window.console.error = function(str){log.push(str)}
74
+ }
69
75
  expect(Foo).to render_static_html('<div>12-string</div>').with_params(foo1: 12, foo2: "string")
76
+ `window.console.warn = org_warn_console; window.console.error = org_error_console;`
77
+
78
+ expect(`log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo`\nProvided prop `foo1` could not be converted to String/)
70
79
  end
71
80
 
72
81
  it 'logs error in warning if validation failed' do
@@ -201,13 +201,6 @@ RSpec.describe React, type: :component do
201
201
  end
202
202
  end
203
203
 
204
- describe "render_to_string" do
205
- it "should render a React.Element to string" do
206
- ele = React.create_element('span') { "lorem" }
207
- expect(React.render_to_string(ele)).to be_kind_of(String)
208
- end
209
- end
210
-
211
204
  describe "unmount_component_at_node" do
212
205
  async "should unmount component at node" do
213
206
  div = `document.createElement("div")`
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ if opal?
4
+
5
+ describe 'Refs callback' do
6
+ before do
7
+ stub_const 'Foo', Class.new
8
+ Foo.class_eval do
9
+ include React::Component
10
+ end
11
+ end
12
+
13
+ it "is invoked with the actual Ruby instance" do
14
+ stub_const 'Bar', Class.new
15
+ Bar.class_eval do
16
+ include React::Component
17
+ def render
18
+ React.create_element('div')
19
+ end
20
+ end
21
+
22
+ Foo.class_eval do
23
+ def my_bar=(bar)
24
+ $bar = bar
25
+ end
26
+
27
+ def render
28
+ React.create_element(Bar, ref: method(:my_bar=).to_proc)
29
+ end
30
+ end
31
+
32
+ element = React.create_element(Foo)
33
+ React::Test::Utils.render_into_document(element)
34
+ expect($bar).to be_a(Bar)
35
+ $bar = nil
36
+ end
37
+
38
+ it "is invoked with the actual DOM node" do
39
+ Foo.class_eval do
40
+ def my_div=(div)
41
+ $div = div
42
+ end
43
+
44
+ def render
45
+ React.create_element('div', ref: method(:my_div=).to_proc)
46
+ end
47
+ end
48
+
49
+ element = React.create_element(Foo)
50
+ React::Test::Utils.render_into_document(element)
51
+ expect(`#{$div}.nodeType`).to eq(1)
52
+ $div = nil
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+
3
+ if opal?
4
+
5
+ RSpec.describe React::Server do
6
+ after(:each) do
7
+ React::API.clear_component_class_cache
8
+ end
9
+
10
+ describe "render_to_string" do
11
+ it "should render a React.Element to string" do
12
+ ele = React.create_element('span') { "lorem" }
13
+ expect(React::Server.render_to_string(ele)).to be_kind_of(String)
14
+ end
15
+ end
16
+
17
+ describe "render_to_static_markup" do
18
+ it "should render a React.Element to static markup" do
19
+ ele = React.create_element('span') { "lorem" }
20
+ expect(React::Server.render_to_static_markup(ele)).to eq("<span>lorem</span>")
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -2,13 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  if opal?
4
4
  describe 'React::State' do
5
- it "can created static exported states" do
5
+ it "can create dynamically initialized exported states" do
6
6
  stub_const 'Foo', Class.new
7
7
  Foo.class_eval do
8
8
  include React::Component
9
9
  export_state(:foo) { 'bar' }
10
10
  end
11
-
11
+ Hyperloop::Application::Boot.run
12
12
  expect(Foo.foo).to eq('bar')
13
13
  end
14
14
 
@@ -45,7 +45,7 @@ describe 'React::State' do
45
45
  var org_error_console = window.console.error;
46
46
  window.console.warn = window.console.error = function(str){log.push(str)}
47
47
  }
48
- markup = React.render_to_static_markup(React.create_element(StateTest))
48
+ markup = React::Server.render_to_static_markup(React.create_element(StateTest))
49
49
  `window.console.warn = org_warn_console; window.console.error = org_error_console;`
50
50
  expect(markup).to eq('<span>Boom</span>')
51
51
  expect(StateTest.boom).to be_falsy
@@ -45,7 +45,7 @@ def render_top_level(controller, component_name)
45
45
  render_params: {}
46
46
  }
47
47
  element = React.create_element(React::TopLevelRailsComponent, params)
48
- React.render_to_static_markup(element)
48
+ React::Server.render_to_static_markup(element)
49
49
  end
50
50
 
51
51
  describe React::TopLevelRailsComponent do
@@ -15,14 +15,44 @@ end
15
15
 
16
16
  if RUBY_ENGINE == 'opal'
17
17
  require File.expand_path('../vendor/jquery-2.2.4.min', __FILE__)
18
- require 'react/react-source'
18
+ require 'react/react-source-browser'
19
+ require 'react/react-source-server'
19
20
  require 'hyper-react'
20
21
  require 'react/test/rspec'
21
22
  require 'react/test/utils'
22
23
  require 'react/top_level_render'
24
+ require 'react/ref_callback'
25
+ require 'react/server'
23
26
 
24
27
  require File.expand_path('../support/react/spec_helpers', __FILE__)
25
28
 
29
+ # turn off deprecation warnings for old style name spaces during this test
30
+ module React
31
+ module Component
32
+
33
+ def self.included(base)
34
+ # deprecation_warning base, "The module name React::Component has been deprecated. Use Hyperloop::Component::Mixin instead."
35
+ base.include Hyperloop::Component::Mixin
36
+ end
37
+
38
+ class Base
39
+ def self.inherited(child)
40
+ # unless child.to_s == "React::Component::HyperTestDummy"
41
+ # React::Component.deprecation_warning child, "The class name React::Component::Base has been deprecated. Use Hyperloop::Component instead."
42
+ # end
43
+ child.include(ComponentNoNotice)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ module React
50
+ class State
51
+ # this messes with lots of tests, these tests will be retested in the new hyper-component gem tests
52
+ ALWAYS_UPDATE_STATE_AFTER_RENDER = false
53
+ end
54
+ end
55
+
26
56
  module Opal
27
57
  module RSpec
28
58
  module AsyncHelpers
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyper-react
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Chang
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-12-13 00:00:00.000000000 Z
13
+ date: 2017-03-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: opal
@@ -54,6 +54,34 @@ dependencies:
54
54
  - - ">="
55
55
  - !ruby/object:Gem::Version
56
56
  version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: hyper-store
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: hyperloop-config
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
57
85
  - !ruby/object:Gem::Dependency
58
86
  name: rake
59
87
  requirement: !ruby/object:Gem::Requirement
@@ -180,6 +208,34 @@ dependencies:
180
208
  - - ">="
181
209
  - !ruby/object:Gem::Version
182
210
  version: '0'
211
+ - !ruby/object:Gem::Dependency
212
+ name: nokogiri
213
+ requirement: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - "<"
216
+ - !ruby/object:Gem::Version
217
+ version: '1.7'
218
+ type: :development
219
+ prerelease: false
220
+ version_requirements: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - "<"
223
+ - !ruby/object:Gem::Version
224
+ version: '1.7'
225
+ - !ruby/object:Gem::Dependency
226
+ name: rubocop
227
+ requirement: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - ">="
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ type: :development
233
+ prerelease: false
234
+ version_requirements: !ruby/object:Gem::Requirement
235
+ requirements:
236
+ - - ">="
237
+ - !ruby/object:Gem::Version
238
+ version: '0'
183
239
  - !ruby/object:Gem::Dependency
184
240
  name: sqlite3
185
241
  requirement: !ruby/object:Gem::Requirement
@@ -236,6 +292,7 @@ files:
236
292
  - gemfiles/opal_0.9_react_13.gemfile
237
293
  - gemfiles/opal_0.9_react_14.gemfile
238
294
  - gemfiles/opal_0.9_react_15.gemfile
295
+ - gemfiles/opal_master_react_15.gemfile
239
296
  - hyper-react.gemspec
240
297
  - lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb
241
298
  - lib/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb
@@ -261,6 +318,9 @@ files:
261
318
  - lib/react/component/props_wrapper.rb
262
319
  - lib/react/component/should_component_update.rb
263
320
  - lib/react/component/tags.rb
321
+ - lib/react/config.rb
322
+ - lib/react/config/client.rb.erb
323
+ - lib/react/config/server.rb
264
324
  - lib/react/element.rb
265
325
  - lib/react/event.rb
266
326
  - lib/react/ext/hash.rb
@@ -269,10 +329,13 @@ files:
269
329
  - lib/react/hash.rb
270
330
  - lib/react/native_library.rb
271
331
  - lib/react/object.rb
272
- - lib/react/observable.rb
332
+ - lib/react/react-source-browser.rb
333
+ - lib/react/react-source-server.rb
273
334
  - lib/react/react-source.rb
335
+ - lib/react/ref_callback.rb
274
336
  - lib/react/rendering_context.rb
275
- - lib/react/state.rb
337
+ - lib/react/server.rb
338
+ - lib/react/state_wrapper.rb
276
339
  - lib/react/test.rb
277
340
  - lib/react/test/dsl.rb
278
341
  - lib/react/test/matchers/render_html_matcher.rb
@@ -294,10 +357,6 @@ files:
294
357
  - lib/reactrb/auto-import.rb
295
358
  - lib/reactrb/deep-compare.rb
296
359
  - lib/reactrb/new-event-name-convention.rb
297
- - lib/sources/react-latest.js
298
- - lib/sources/react-v13.js
299
- - lib/sources/react-v14.js
300
- - lib/sources/react-v15.js
301
360
  - logo1.png
302
361
  - logo2.png
303
362
  - logo3.png
@@ -316,6 +375,8 @@ files:
316
375
  - spec/react/opal_jquery_extensions_spec.rb
317
376
  - spec/react/param_declaration_spec.rb
318
377
  - spec/react/react_spec.rb
378
+ - spec/react/refs_callback_spec.rb
379
+ - spec/react/server_spec.rb
319
380
  - spec/react/state_spec.rb
320
381
  - spec/react/test/dsl_spec.rb
321
382
  - spec/react/test/matchers/render_html_matcher_spec.rb
@@ -354,7 +415,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
354
415
  version: '0'
355
416
  requirements: []
356
417
  rubyforge_project:
357
- rubygems_version: 2.2.2
418
+ rubygems_version: 2.5.1
358
419
  signing_key:
359
420
  specification_version: 4
360
421
  summary: Opal Ruby wrapper of React.js library.
@@ -373,6 +434,8 @@ test_files:
373
434
  - spec/react/opal_jquery_extensions_spec.rb
374
435
  - spec/react/param_declaration_spec.rb
375
436
  - spec/react/react_spec.rb
437
+ - spec/react/refs_callback_spec.rb
438
+ - spec/react/server_spec.rb
376
439
  - spec/react/state_spec.rb
377
440
  - spec/react/test/dsl_spec.rb
378
441
  - spec/react/test/matchers/render_html_matcher_spec.rb
@@ -1,29 +0,0 @@
1
- module React
2
- class Observable
3
- def initialize(value, on_change = nil, &block)
4
- @value = value
5
- @on_change = on_change || block
6
- end
7
-
8
- def method_missing(method_sym, *args, &block)
9
- @value.send(method_sym, *args, &block).tap { |result| @on_change.call @value }
10
- end
11
-
12
- def respond_to?(method, *args)
13
- if [:call, :to_proc].include? method
14
- true
15
- else
16
- @value.respond_to? method, *args
17
- end
18
- end
19
-
20
- def call(new_value)
21
- @on_change.call new_value
22
- @value = new_value
23
- end
24
-
25
- def to_proc
26
- lambda { |arg = @value| @on_change.call arg }
27
- end
28
- end
29
- end
@@ -1,191 +0,0 @@
1
- module React
2
- class StateWrapper < BasicObject
3
- def initialize(native, from)
4
- @state_hash = Hash.new(`#{native}.state`)
5
- @from = from
6
- end
7
-
8
- def [](state)
9
- @state_hash[state]
10
- end
11
-
12
- def []=(state, new_value)
13
- @state_hash[state] = new_value
14
- end
15
-
16
- def method_missing(method, *args)
17
- if match = method.match(/^(.+)\!$/)
18
- key_name = $1
19
- if args.count > 0
20
- current_value = State.get_state(@from, match[1])
21
- State.set_state(@from, key_name, args[0])
22
- current_value
23
- else
24
- current_state = State.get_state(@from, match[1])
25
- State.set_state(@from, key_name, current_state)
26
- Observable.new(current_state) do |update|
27
- State.set_state(@from, key_name, update)
28
- end
29
- end
30
- else
31
- State.get_state(@from, method)
32
- end
33
- end
34
- end
35
-
36
- class State
37
-
38
- @rendering_level = 0
39
-
40
- class << self
41
- attr_reader :current_observer
42
-
43
- def has_observers?(object, name)
44
- !observers_by_name[object][name].empty?
45
- end
46
-
47
- def bulk_update
48
- saved_bulk_update_flag = @bulk_update_flag
49
- @bulk_update_flag = true
50
- yield
51
- ensure
52
- @bulk_update_flag = saved_bulk_update_flag
53
- end
54
-
55
- def set_state2(object, name, value, updates, exclusions = nil)
56
- # set object's name state to value, tell all observers it has changed.
57
- # Observers must implement update_react_js_state
58
- object_needs_notification = object.respond_to? :update_react_js_state
59
- observers_by_name[object][name].dup.each do |observer|
60
- next if exclusions && exclusions.include?(observer)
61
- updates[observer] += [object, name, value]
62
- object_needs_notification = false if object == observer
63
- end
64
- updates[object] += [nil, name, value] if object_needs_notification
65
- end
66
-
67
- def initialize_states(object, initial_values) # initialize objects' name/value pairs
68
- states[object].merge!(initial_values || {})
69
- end
70
-
71
- def get_state(object, name, current_observer = @current_observer)
72
- # get current value of name for object, remember that the current object depends on this state,
73
- # current observer can be overriden with last param
74
- if current_observer && !new_observers[current_observer][object].include?(name)
75
- new_observers[current_observer][object] << name
76
- end
77
- if @delayed_updates && @delayed_updates[object][name]
78
- @delayed_updates[object][name][1] << current_observer
79
- end
80
- states[object][name]
81
- end
82
-
83
- def set_state(object, name, value, delay=nil)
84
- states[object][name] = value
85
- if delay || @bulk_update_flag
86
- @delayed_updates ||= Hash.new { |h, k| h[k] = {} }
87
- @delayed_updates[object][name] = [value, Set.new]
88
- @delayed_updater ||= after(0.001) do
89
- delayed_updates = @delayed_updates
90
- @delayed_updates = Hash.new { |h, k| h[k] = {} } # could this be nil???
91
- @delayed_updater = nil
92
- updates = Hash.new { |hash, key| hash[key] = Array.new }
93
- delayed_updates.each do |object, name_hash|
94
- name_hash.each do |name, value_and_set|
95
- set_state2(object, name, value_and_set[0], updates, value_and_set[1])
96
- end
97
- end
98
- updates.each { |observer, args| observer.update_react_js_state(*args) }
99
- end
100
- elsif @rendering_level == 0
101
- updates = Hash.new { |hash, key| hash[key] = Array.new }
102
- set_state2(object, name, value, updates)
103
- updates.each { |observer, args| observer.update_react_js_state(*args) }
104
- end
105
- value
106
- end
107
-
108
- def notify_observers(object, name, value)
109
- object_needs_notification = object.respond_to? :update_react_js_state
110
- observers_by_name[object][name].dup.each do |observer|
111
- observer.update_react_js_state(object, name, value)
112
- object_needs_notification = false if object == observer
113
- end
114
- object.update_react_js_state(nil, name, value) if object_needs_notification
115
- end
116
-
117
- def notify_observers_after_thread_completes(object, name, value)
118
- (@delayed_updates ||= []) << [object, name, value]
119
- @delayed_updater ||= after(0) do
120
- delayed_updates = @delayed_updates
121
- @delayed_updates = []
122
- @delayed_updater = nil
123
- delayed_updates.each { |args| notify_observers(*args) }
124
- end
125
- end
126
-
127
- def will_be_observing?(object, name, current_observer)
128
- current_observer && new_observers[current_observer][object].include?(name)
129
- end
130
-
131
- def is_observing?(object, name, current_observer)
132
- current_observer && observers_by_name[object][name].include?(current_observer)
133
- end
134
-
135
- def update_states_to_observe(current_observer = @current_observer) # should be called after the last after_render callback, currently called after components render method
136
- raise "update_states_to_observer called outside of watch block" unless current_observer
137
- current_observers[current_observer].each do |object, names|
138
- names.each do |name|
139
- observers_by_name[object][name].delete(current_observer)
140
- end
141
- end
142
- observers = current_observers[current_observer] = new_observers[current_observer]
143
- new_observers.delete(current_observer)
144
- observers.each do |object, names|
145
- names.each do |name|
146
- observers_by_name[object][name] << current_observer
147
- end
148
- end
149
- end
150
-
151
- def remove # call after component is unmounted
152
- raise "remove called outside of watch block" unless @current_observer
153
- current_observers[@current_observer].each do |object, names|
154
- names.each do |name|
155
- observers_by_name[object][name].delete(@current_observer)
156
- end
157
- end
158
- current_observers.delete(@current_observer)
159
- end
160
-
161
- def set_state_context_to(observer, rendering = nil) # wrap all execution that may set or get states in a block so we know which observer is executing
162
- if `typeof Opal.global.reactive_ruby_timing !== 'undefined'`
163
- @nesting_level = (@nesting_level || 0) + 1
164
- start_time = Time.now.to_f
165
- observer_name = (observer.class.respond_to?(:name) ? observer.class.name : observer.to_s) rescue "object:#{observer.object_id}"
166
- end
167
- saved_current_observer = @current_observer
168
- @current_observer = observer
169
- @rendering_level += 1 if rendering
170
- return_value = yield
171
- return_value
172
- ensure
173
- @current_observer = saved_current_observer
174
- @rendering_level -= 1 if rendering
175
- @nesting_level = [0, @nesting_level - 1].max if `typeof Opal.global.reactive_ruby_timing !== 'undefined'`
176
- return_value
177
- end
178
-
179
- def states
180
- @states ||= Hash.new { |h, k| h[k] = {} }
181
- end
182
-
183
- [:new_observers, :current_observers, :observers_by_name].each do |method_name|
184
- define_method(method_name) do
185
- instance_variable_get("@#{method_name}") ||
186
- instance_variable_set("@#{method_name}", Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = [] } })
187
- end
188
- end
189
- end
190
- end
191
- end