hyper-component 1.0.alpha1.3 → 1.0.alpha1.8

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/Gemfile +5 -0
  4. data/hyper-component.gemspec +8 -16
  5. data/lib/hyper-component.rb +8 -1
  6. data/lib/hyperstack/component.rb +46 -10
  7. data/lib/hyperstack/component/children.rb +1 -1
  8. data/lib/hyperstack/component/element.rb +93 -21
  9. data/lib/hyperstack/component/event.rb +1 -1
  10. data/lib/hyperstack/component/free_render.rb +21 -0
  11. data/lib/hyperstack/component/isomorphic_helpers.rb +13 -10
  12. data/lib/hyperstack/component/version.rb +1 -1
  13. data/lib/hyperstack/component/while_loading.rb +1 -1
  14. data/lib/hyperstack/ext/component/array.rb +20 -0
  15. data/lib/hyperstack/ext/component/element.rb +5 -7
  16. data/lib/hyperstack/ext/component/enumerable.rb +18 -0
  17. data/lib/hyperstack/ext/component/kernel.rb +7 -0
  18. data/lib/hyperstack/ext/component/time.rb +5 -0
  19. data/lib/hyperstack/internal/component/class_methods.rb +4 -3
  20. data/lib/hyperstack/internal/component/haml.rb +3 -12
  21. data/lib/hyperstack/internal/component/props_wrapper.rb +13 -11
  22. data/lib/hyperstack/internal/component/rails/component_mount.rb +12 -0
  23. data/lib/hyperstack/internal/component/rails/controller_helper.rb +1 -1
  24. data/lib/hyperstack/internal/component/rails/railtie.rb +3 -2
  25. data/lib/hyperstack/internal/component/rails/server_rendering/contextual_renderer.rb +5 -1
  26. data/lib/hyperstack/internal/component/rails/server_rendering/hyper_asset_container.rb +4 -2
  27. data/lib/hyperstack/internal/component/react_wrapper.rb +77 -60
  28. data/lib/hyperstack/internal/component/rendering_context.rb +80 -44
  29. data/lib/hyperstack/internal/component/rescue_wrapper.rb +1 -1
  30. data/lib/hyperstack/internal/component/tags.rb +12 -3
  31. data/lib/react/react-source.rb +2 -2
  32. metadata +51 -89
  33. data/Gemfile.lock +0 -364
@@ -1,5 +1,5 @@
1
1
  module Hyperstack
2
2
  module Component
3
- VERSION = '1.0.alpha1.3' # '1.0.alpha1.3'
3
+ VERSION = '1.0.alpha1.8' # '1.0.alpha1.5'
4
4
  end
5
5
  end
@@ -16,7 +16,7 @@ module Hyperstack
16
16
  if Hyperstack::Component::IsomorphicHelpers.on_opal_client?
17
17
  %x{
18
18
  function onError(event) {
19
- if (event.message.startsWith('Uncaught NotQuiet: ')) event.preventDefault();
19
+ if (event.message.match(/^Uncaught NotQuiet: /)) event.preventDefault();
20
20
  }
21
21
 
22
22
  window.addEventListener('error', onError);
@@ -0,0 +1,20 @@
1
+ # from Rails 6.0 activesupport. Remove once defined by Opal activesupport
2
+ class Array
3
+ # Removes and returns the elements for which the block returns a true value.
4
+ # If no block is given, an Enumerator is returned instead.
5
+ #
6
+ # numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7
+ # odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
8
+ # numbers # => [0, 2, 4, 6, 8]
9
+ def extract!
10
+ return to_enum(:extract!) { size } unless block_given?
11
+
12
+ extracted_elements = []
13
+
14
+ reject! do |element|
15
+ extracted_elements << element if yield(element)
16
+ end
17
+
18
+ extracted_elements
19
+ end
20
+ end
@@ -1,11 +1,9 @@
1
1
  Element.instance_eval do
2
2
  def self.find(selector)
3
- selector = begin
4
- selector.dom_node
5
- rescue
6
- selector
7
- end if `#{selector}.$dom_node !== undefined`
8
- `$(#{selector})`
3
+ if `typeof #{selector}['$respond_to?'] == 'function'` && selector.respond_to?(:dom_node)
4
+ selector = selector.dom_node
5
+ end
6
+ `jQuery(#{selector})`
9
7
  end
10
8
 
11
9
  def self.[](selector)
@@ -37,7 +35,7 @@ Element.instance_eval do
37
35
  # see react-rails documentation for more details
38
36
 
39
37
  %x{
40
- $.fn.mount_components = function() {
38
+ jQuery.fn.mount_components = function() {
41
39
  this.each(function(e) { ReactRailsUJS.mountComponents(e[0]) })
42
40
  return this;
43
41
  }
@@ -0,0 +1,18 @@
1
+ # from Rails 6.0 activesupport. Remove once defined by Opal activesupport
2
+ module Enumerable
3
+ INDEX_WITH_DEFAULT = Object.new
4
+ private_constant :INDEX_WITH_DEFAULT
5
+ def index_with(default = INDEX_WITH_DEFAULT)
6
+ if block_given?
7
+ result = {}
8
+ each { |elem| result[elem] = yield(elem) }
9
+ result
10
+ elsif default != INDEX_WITH_DEFAULT
11
+ result = {}
12
+ each { |elem| result[elem] = default }
13
+ result
14
+ else
15
+ to_enum(:index_with) { size if respond_to?(:size) }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ module Kernel
2
+ def pause(s, &block)
3
+ Promise.new.tap { |p| after(s) { p.resolve(*(block && [block.call])) }}
4
+ end
5
+ alias busy_sleep sleep
6
+ alias sleep pause
7
+ end
@@ -0,0 +1,5 @@
1
+ class Time
2
+ def to_json
3
+ strftime("%FT%T.%3N%z").to_json
4
+ end
5
+ end
@@ -50,7 +50,7 @@ module Hyperstack
50
50
  def render(container = nil, params = {}, &block)
51
51
  Tags.included(self)
52
52
  if container
53
- container = container.type if container.is_a? Hyperstack::Component::Element
53
+ container = container.element_type if container.is_a? Hyperstack::Component::Element
54
54
  define_method(:__hyperstack_component_render) do
55
55
  __hyperstack_component_select_wrappers do
56
56
  RenderingContext.render(container, params) do
@@ -271,7 +271,8 @@ module Hyperstack
271
271
  ReactWrapper.import_native_component(
272
272
  self, ReactWrapper.eval_native_react_component(component_name)
273
273
  )
274
- define_method(:render) {} # define a dummy render method - will never be called...
274
+ render {}
275
+ #define_method(:render) {} # define a dummy render method - will never be called...
275
276
  rescue Exception => e # rubocop:disable Lint/RescueException : we need to catch everything!
276
277
  raise "#{self} cannot import '#{component_name}': #{e.message}."
277
278
  # rubocop:enable Lint/RescueException
@@ -291,7 +292,7 @@ module Hyperstack
291
292
  end
292
293
 
293
294
  def to_n
294
- ReactWrapper.class_eval('@@component_classes')[self]
295
+ Hyperstack::Internal::Component::ReactWrapper.create_native_react_class(self)
295
296
  end
296
297
  end
297
298
  end
@@ -27,7 +27,9 @@ module Hyperstack
27
27
  Hyperstack::Internal::Component::RenderingContext.replace(
28
28
  self,
29
29
  Hyperstack::Internal::Component::RenderingContext.build do
30
- Hyperstack::Internal::Component::RenderingContext.render(type, build_new_properties(class_name, args), &new_block)
30
+ Hyperstack::Internal::Component::RenderingContext.render(
31
+ element_type, @properties, args, class: haml_class_name(class_name), &new_block
32
+ )
31
33
  end
32
34
  )
33
35
  end
@@ -39,17 +41,6 @@ module Hyperstack
39
41
  def haml_class_name(class_name)
40
42
  class_name.gsub(/__|_/, '__' => '_', '_' => '-')
41
43
  end
42
-
43
- private
44
-
45
- def build_new_properties(class_name, args)
46
- class_name = haml_class_name(class_name)
47
- new_props = @properties.dup
48
- new_props[:className] = "\
49
- #{class_name} #{new_props[:className]} #{args.delete(:class)} #{args.delete(:className)}\
50
- ".split(' ').uniq.join(' ')
51
- new_props.merge! args
52
- end
53
44
  end
54
45
  end
55
46
  end
@@ -48,21 +48,23 @@ module Hyperstack
48
48
  end
49
49
 
50
50
  def define_param(name, param_type, aka = nil)
51
- meth_name = aka || name
52
- var_name = fix_suffix(aka) || instance_var_name_for(name)
53
- param_definitions[name] = lambda do |props|
54
- @component.instance_variable_set :"@#{var_name}", val = fetch_from_cache(name, param_type, props)
55
- next unless param_accessor_style == :accessors
56
- `#{@component}[#{"$#{meth_name}"}] = function() { return #{val} }`
57
- # @component.define_singleton_method(name) { val } if param_accessor_style == :accessors
51
+ if param_accessor_style != :legacy || aka
52
+ meth_name = aka || name
53
+ var_name = fix_suffix(aka) || instance_var_name_for(name)
54
+ param_definitions[name] = lambda do |props|
55
+ @component.instance_variable_set :"@#{var_name}", val = fetch_from_cache(name, param_type, props)
56
+ next unless param_accessor_style == :accessors
57
+ `#{@component}[#{"$#{meth_name}"}] = function() { return #{val} }`
58
+ # @component.define_singleton_method(name) { val } if param_accessor_style == :accessors
59
+ end
60
+ return if %i[hyperstack accessors].include? param_accessor_style
58
61
  end
59
- return if %i[hyperstack accessors].include? param_accessor_style
60
62
  if param_type == Proc
61
- define_method(meth_name.to_sym) do |*args, &block|
63
+ define_method(name.to_sym) do |*args, &block|
62
64
  props[name].call(*args, &block) if props[name]
63
65
  end
64
66
  else
65
- define_method(meth_name.to_sym) do
67
+ define_method(name.to_sym) do
66
68
  fetch_from_cache(name, param_type, props)
67
69
  end
68
70
  end
@@ -88,7 +90,7 @@ module Hyperstack
88
90
 
89
91
  def initialize(component, incoming = nil)
90
92
  @component = component
91
- return if param_accessor_style == :legacy
93
+ #return if param_accessor_style == :legacy
92
94
  self.class.param_definitions.each_value do |initializer|
93
95
  instance_exec(incoming || props, &initializer)
94
96
  end
@@ -43,6 +43,9 @@ module Hyperstack
43
43
  end
44
44
 
45
45
  def footers
46
+ return if @hyperstack_footers_rendered
47
+
48
+ @hyperstack_footers_rendered = true
46
49
  Hyperstack::Component::IsomorphicHelpers.prerender_footers(controller)
47
50
  end
48
51
  end
@@ -50,3 +53,12 @@ module Hyperstack
50
53
  end
51
54
  end
52
55
  end
56
+
57
+
58
+ module React
59
+ module Rails
60
+ module ViewHelper
61
+ alias mount_component react_component
62
+ end
63
+ end
64
+ end
@@ -22,7 +22,7 @@ module ActionController
22
22
  @render_params = args.shift || {}
23
23
  options = args[0] || {}
24
24
  return if performed?
25
- render inline: '<%= react_component @component_name, @render_params %>',
25
+ render inline: '<%= mount_component @component_name, @render_params %>',
26
26
  layout: options.key?(:layout) ? options[:layout].to_s : :default
27
27
  rescue Exception => e
28
28
  m = /^RuntimeError: Hyperstack::Internal::Component::Redirect (.+) status: (.+)$/.match(e.message)
@@ -12,8 +12,9 @@ module Hyperstack
12
12
  end
13
13
  config.after_initialize do
14
14
  class ::HyperstackController < ::ApplicationController
15
- def action_missing(_name)
16
- render_component
15
+ def action_missing(*)
16
+ parts = params[:action].split('__')
17
+ render_component (parts[0..-2]+[parts.last.camelize]).join('::')
17
18
  end
18
19
  end
19
20
  end
@@ -13,7 +13,11 @@ module Hyperstack
13
13
 
14
14
  class ContextualRenderer < React::ServerRendering::BundleRenderer
15
15
  def initialize(options = {})
16
- super(options)
16
+ unless v8_runtime?
17
+ raise "Hyperstack prerendering only works with MiniRacer. Add 'mini_racer' to your Gemfile"
18
+ end
19
+
20
+ super({ files: ['hyperstack-prerender-loader.js'] }.merge(options))
17
21
  ComponentLoader.new(v8_context).load
18
22
  end
19
23
 
@@ -9,7 +9,9 @@ module Hyperstack
9
9
  module ServerRendering
10
10
  class HyperTestAssetContainer
11
11
  def find_asset(logical_path)
12
- ::Rails.cache.read(logical_path)
12
+ # we skip the container if it raises an error so we
13
+ # don't care if we are running under hyperspec or not
14
+ HyperSpec::Internal::Controller.cache_read(logical_path)
13
15
  end
14
16
  end
15
17
 
@@ -24,7 +26,7 @@ module Hyperstack
24
26
  if React::ServerRendering::WebpackerManifestContainer.compatible?
25
27
  @ass_containers << React::ServerRendering::WebpackerManifestContainer.new
26
28
  end
27
- @ass_containers << HyperTestAssetContainer.new if ::Rails.env.test?
29
+ @ass_containers << HyperTestAssetContainer.new
28
30
  end
29
31
 
30
32
  def find_asset(logical_path)
@@ -18,6 +18,10 @@ module Hyperstack
18
18
  class ReactWrapper
19
19
  @@component_classes = {}
20
20
 
21
+ def self.stateless?(ncc)
22
+ `typeof #{ncc} === 'symbol' || (typeof #{ncc} === 'function' && !(#{ncc}.prototype && #{ncc}.prototype.isReactComponent))`
23
+ end
24
+
21
25
  def self.import_native_component(opal_class, native_class)
22
26
  opal_class.instance_variable_set("@native_import", true)
23
27
  @@component_classes[opal_class] = native_class
@@ -26,12 +30,13 @@ module Hyperstack
26
30
  def self.eval_native_react_component(name)
27
31
  component = `eval(name)`
28
32
  raise "#{name} is not defined" if `#{component} === undefined`
33
+
34
+ component = `component.default` if `component.__esModule`
29
35
  is_component_class = `#{component}.prototype !== undefined` &&
30
36
  (`!!#{component}.prototype.isReactComponent` ||
31
37
  `!!#{component}.prototype.render`)
32
- is_functional_component = `typeof #{component} === "function"`
33
38
  has_render_method = `typeof #{component}.render === "function"`
34
- unless is_component_class || is_functional_component || has_render_method
39
+ unless is_component_class || stateless?(component) || has_render_method
35
40
  raise 'does not appear to be a native react component'
36
41
  end
37
42
  component
@@ -39,9 +44,11 @@ module Hyperstack
39
44
 
40
45
  def self.native_react_component?(name = nil)
41
46
  return false unless name
47
+
42
48
  eval_native_react_component(name)
43
49
  true
44
- rescue
50
+ # Exception to be compatible with all versions of opal
51
+ rescue Exception # rubocop:disable Lint/RescueException
45
52
  false
46
53
  end
47
54
 
@@ -60,93 +67,81 @@ module Hyperstack
60
67
  end
61
68
 
62
69
  def self.create_native_react_class(type)
70
+ raise "createReactClass is undefined. Add the 'react-create-class' npm module, and import it as 'createReactClass'" if `typeof(createReactClass)=='undefined'`
63
71
  raise "Provided class should define `render` method" if !(type.method_defined? :render)
64
- render_fn = (type.method_defined? :_render_wrapper) ? :_render_wrapper : :render
72
+ old_school = !type.method_defined?(:_render_wrapper)
73
+ render_fn = old_school ? :render : :_render_wrapper
65
74
  # this was hashing type.to_s, not sure why but .to_s does not work as it Foo::Bar::View.to_s just returns "View"
66
-
67
75
  @@component_classes[type] ||= begin
68
76
  comp = %x{
69
- class extends React.Component {
70
- constructor(props) {
71
- super(props);
77
+ createReactClass({
78
+ getInitialState: function() {
72
79
  this.mixins = #{type.respond_to?(:native_mixins) ? type.native_mixins : `[]`};
73
80
  this.statics = #{type.respond_to?(:static_call_backs) ? type.static_call_backs.to_n : `{}`};
74
- this.state = {};
75
81
  this.__opalInstanceInitializedState = false;
76
82
  this.__opalInstanceSyncSetState = true;
77
83
  this.__opalInstance = #{type.new(`this`)};
78
84
  this.__opalInstanceInitializedState = true;
79
85
  this.__opalInstanceSyncSetState = false;
80
86
  this.__name = #{type.name};
81
- }
82
- static get displayName() {
83
- if (typeof this.__name != "undefined") {
84
- return this.__name;
85
- } else {
86
- return #{type.name};
87
- }
88
- }
89
- static set displayName(name) {
90
- this.__name = name;
91
- }
92
- static get defaultProps() {
87
+ return {}
88
+ },
89
+ displayName: #{type.name},
90
+ getDefaultProps: function() {
93
91
  return #{type.respond_to?(:default_props) ? type.default_props.to_n : `{}`};
94
- }
95
- static get propTypes() {
96
- return #{type.respond_to?(:prop_types) ? type.prop_types.to_n : `{}`};
97
- }
98
- componentWillMount() {
92
+ },
93
+ propTypes: #{type.respond_to?(:prop_types) ? type.prop_types.to_n : `{}`},
94
+ componentWillMount: old_school && function() {
99
95
  if (#{type.method_defined? :component_will_mount}) {
100
96
  this.__opalInstanceSyncSetState = true;
101
97
  this.__opalInstance.$component_will_mount();
102
98
  this.__opalInstanceSyncSetState = false;
103
99
  }
104
- }
105
- componentDidMount() {
100
+ },
101
+ componentDidMount: function() {
106
102
  this.__opalInstance.__hyperstack_component_is_mounted = true
107
103
  if (#{type.method_defined? :component_did_mount}) {
108
104
  this.__opalInstanceSyncSetState = false;
109
105
  this.__opalInstance.$component_did_mount();
110
106
  }
111
- }
112
- componentWillReceiveProps(next_props) {
107
+ },
108
+ UNSAFE_componentWillReceiveProps: function(next_props) {
113
109
  if (#{type.method_defined? :component_will_receive_props}) {
114
110
  this.__opalInstanceSyncSetState = true;
115
111
  this.__opalInstance.$component_will_receive_props(Opal.Hash.$new(next_props));
116
112
  this.__opalInstanceSyncSetState = false;
117
113
  }
118
- }
119
- shouldComponentUpdate(next_props, next_state) {
114
+ },
115
+ shouldComponentUpdate: function(next_props, next_state) {
120
116
  if (#{type.method_defined? :should_component_update?}) {
121
117
  this.__opalInstanceSyncSetState = false;
122
118
  return this.__opalInstance["$should_component_update?"](Opal.Hash.$new(next_props), Opal.Hash.$new(next_state));
123
119
  } else { return true; }
124
- }
125
- componentWillUpdate(next_props, next_state) {
120
+ },
121
+ UNSAFE_componentWillUpdate: function(next_props, next_state) {
126
122
  if (#{type.method_defined? :component_will_update}) {
127
123
  this.__opalInstanceSyncSetState = false;
128
124
  this.__opalInstance.$component_will_update(Opal.Hash.$new(next_props), Opal.Hash.$new(next_state));
129
125
  }
130
- }
131
- componentDidUpdate(prev_props, prev_state) {
126
+ },
127
+ componentDidUpdate: function(prev_props, prev_state) {
132
128
  if (#{type.method_defined? :component_did_update}) {
133
129
  this.__opalInstanceSyncSetState = false;
134
130
  this.__opalInstance.$component_did_update(Opal.Hash.$new(prev_props), Opal.Hash.$new(prev_state));
135
131
  }
136
- }
137
- componentWillUnmount() {
132
+ },
133
+ componentWillUnmount: function() {
138
134
  if (#{type.method_defined? :component_will_unmount}) {
139
135
  this.__opalInstanceSyncSetState = false;
140
136
  this.__opalInstance.$component_will_unmount();
141
137
  }
142
138
  this.__opalInstance.__hyperstack_component_is_mounted = false;
143
- }
144
-
145
- render() {
139
+ },
140
+ render: function() {
146
141
  this.__opalInstanceSyncSetState = false;
147
142
  return this.__opalInstance.$send(render_fn).$to_n();
148
143
  }
149
- }
144
+ })
150
145
  }
151
146
  # check to see if there is an after_error callback. If there is add a
152
147
  # componentDidCatch handler. Because legacy behavior is to allow any object
@@ -178,7 +173,9 @@ module Hyperstack
178
173
  end
179
174
 
180
175
  # Convert Passed in properties
181
- properties = convert_props(args)
176
+ ele = nil # create nil var for the ref to use
177
+ ref = ->(ref) { ele._update_ref(ref) } unless stateless?(ncc)
178
+ properties = convert_props(type, { ref: ref }, *args)
182
179
  params << properties.shallow_to_n
183
180
 
184
181
  # Children Nodes
@@ -190,14 +187,17 @@ module Hyperstack
190
187
  }
191
188
  }
192
189
  end
193
- Hyperstack::Component::Element.new(`React.createElement.apply(null, #{params})`, type, properties, block)
190
+ # assign to ele so that the ref callback can use it
191
+ ele = Hyperstack::Component::Element.new(
192
+ `React.createElement.apply(null, #{params})`, type, properties, block
193
+ )
194
194
  end
195
195
 
196
196
  def self.clear_component_class_cache
197
197
  @@component_classes = {}
198
198
  end
199
199
 
200
- def self.convert_props(args)
200
+ def self.convert_props(type, *args)
201
201
  # merge args together into a single properties hash
202
202
  properties = {}
203
203
  args.each do |arg|
@@ -234,33 +234,50 @@ module Hyperstack
234
234
  # process properties according to react rules
235
235
  props = {}
236
236
  properties.each do |key, value|
237
- if ["style", "dangerously_set_inner_HTML"].include? key
237
+ if %w[style dangerously_set_inner_HTML].include? key
238
238
  props[lower_camelize(key)] = value.to_n
239
239
 
240
- elsif key == "className"
240
+ elsif key == :className
241
241
  props[key] = value.join(' ')
242
242
 
243
- elsif key == "key"
244
- props["key"] = value.to_key
243
+ elsif key == :key
244
+ props[:key] = value.to_key
245
+
246
+ elsif key == :init
247
+ if %w[select textarea].include? type
248
+ key = :defaultValue
249
+ elsif type == :input
250
+ key = if %w[radio checkbox].include? properties[:type]
251
+ :defaultChecked
252
+ else
253
+ :defaultValue
254
+ end
255
+ end
256
+ props[key] = value
245
257
 
246
258
  elsif key == 'ref'
259
+ next unless value
247
260
  unless value.respond_to?(:call)
248
261
  raise "The ref and dom params must be given a Proc.\n"\
249
262
  "If you want to capture the ref in an instance variable use the `set` method.\n"\
250
263
  "For example `ref: set(:TheRef)` will capture assign the ref to `@TheRef`\n"
251
264
  end
252
- props[key] = %x{
253
- function(dom_node){
254
- if (dom_node !== null && dom_node.__opalInstance !== undefined && dom_node.__opalInstance !== null) {
255
- #{ Hyperstack::Internal::State::Mapper.ignore_mutations { value.call(`dom_node.__opalInstance`) } };
256
- } else if(dom_node !== null && ReactDOM.findDOMNode !== undefined && dom_node.nodeType === undefined) {
257
- #{ Hyperstack::Internal::State::Mapper.ignore_mutations { value.call(`ReactDOM.findDOMNode(dom_node)`) } };
258
- } else if(dom_node !== null){
259
- #{ Hyperstack::Internal::State::Mapper.ignore_mutations { value.call(`dom_node`) } };
260
- }
261
- }
265
+ unless `value.__hyperstack_component_ref_is_already_wrapped`
266
+ fn = value
267
+ value = %x{
268
+ function(dom_node){
269
+ if (dom_node !== null && dom_node.__opalInstance !== undefined && dom_node.__opalInstance !== null) {
270
+ #{ Hyperstack::Internal::State::Mapper.ignore_mutations { fn.call(`dom_node.__opalInstance`) } };
271
+ } else if(dom_node !== null && ReactDOM.findDOMNode !== undefined && dom_node.nodeType === undefined) {
272
+ #{ Hyperstack::Internal::State::Mapper.ignore_mutations { fn.call(`ReactDOM.findDOMNode(dom_node)`) } };
273
+ } else if(dom_node !== null){
274
+ #{ Hyperstack::Internal::State::Mapper.ignore_mutations { fn.call(`dom_node`) } };
262
275
  }
263
-
276
+ }
277
+ }
278
+ `value.__hyperstack_component_ref_is_already_wrapped = true`
279
+ end
280
+ props[key] = value
264
281
  elsif key == 'jq_ref'
265
282
  unless value.respond_to?(:call)
266
283
  raise "The ref and dom params must be given a Proc.\n"\