isomorfeus-preact 10.6.20 → 10.6.24

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79141102f4c45c9264382de0ec926a8f9cce4606be4049d8662db3d713184eff
4
- data.tar.gz: 3a8b5bcc189fcfcf40c31322ff85c48a9ae71e7d9f0833412429abe3886e06f2
3
+ metadata.gz: 6bf4eaa022b76cf456aff65c04257f0f7d8877ac285c9b0dfcece7a4c95d6f93
4
+ data.tar.gz: c8d50c5a3a92e2ebad7a215746f0fd0aa21f910585187a645fffb6f5bfc4e9fd
5
5
  SHA512:
6
- metadata.gz: e2e5b8e8f24cb6e73120e6cdeb03e41cac9747e1758d13b3c928c75292b68b6ceec44912537848a72733befe6652f17798cb451920d206b3bd71d320fce07838
7
- data.tar.gz: a179f9b3ed757eabfa1471521858845297df8fe53ac5aba16c9d94c5a7ed058b8fc3b48f42d96b9e2c8fd7506cf99389e649bf901782ce3c21c7a6029cff2e68
6
+ metadata.gz: 85cc46da828b1aee16afd1c5f68e251514eabdfc168f6537ce65c084edecf2d43dd96ede48e30fa88ee694cb066e9e5795c84966ac2cea940e493a652133f286
7
+ data.tar.gz: 05a90b9e5fe7165008558dcb226040af5c839bf6a703c80bd73c4ad09212222c411906eb94e1539b1cc4f0c2f153101f5a4b3b96797cf6c35129d0d240edfe5c
@@ -26,12 +26,22 @@ module Browser
26
26
  %x{
27
27
  let value = #@native[#{property_name}];
28
28
  let type = typeof(value);
29
- if (type === 'function') {
30
- return value.apply(#@native, args);
31
- } else if (value === null || type === 'undefined' || (type === 'number' && isNaN(value))) {
32
- return nil;
33
- }
34
- return value;
29
+ try {
30
+ if (type === 'function') {
31
+ return value.apply(#@native, args);
32
+ } else if (type === 'object' && (value instanceof HTMLCollection)) {
33
+ let a = [];
34
+ for(let i=0; i<value.length; i++) {
35
+ a[i] = #{Browser::Element.new(`value.item(i)`)};
36
+ }
37
+ value = a;
38
+ } else if (type === 'object' && (value instanceof HTMLElement)) {
39
+ value = #{Browser::Element.new(value)};
40
+ } else if (value === null || type === 'undefined' || (type === 'number' && isNaN(value))) {
41
+ return nil;
42
+ }
43
+ return value;
44
+ } catch { return value; }
35
45
  }
36
46
  end
37
47
  end
@@ -41,6 +41,8 @@ module Isomorfeus
41
41
  end
42
42
  end
43
43
 
44
+ start_time = Time.now if Isomorfeus.development?
45
+ pass = 1
44
46
  # if location_host and scheme are given and if Transport is loaded, connect and then render,
45
47
  # otherwise do not render because only one pass is required
46
48
  ws_scheme = props[:location_scheme] == 'https:' ? 'wss:' : 'ws:'
@@ -88,6 +90,7 @@ module Isomorfeus
88
90
  end
89
91
  # wait for first pass to finish
90
92
  unless first_pass_skipped
93
+ pass += 1
91
94
  first_pass_finished, exception = Isomorfeus.ssr_contexts[thread_id_asset].exec('return [global.FirstPassFinished, global.Exception ? { message: global.Exception.message, stack: global.Exception.stack } : false ]')
92
95
  Isomorfeus.raise_error(message: "Server Side Rendering: #{exception['message']}", stack: exception['stack']) if exception
93
96
  unless first_pass_finished
@@ -104,7 +107,7 @@ module Isomorfeus
104
107
  if transport_busy
105
108
  start_time = Time.now
106
109
  while transport_busy
107
- break if (Time.now - start_time) > 10
110
+ break if (Time.now - start_time) > 5
108
111
  sleep 0.01
109
112
  transport_busy = Isomorfeus.ssr_contexts[thread_id_asset].exec('return global.Opal.Isomorfeus.Transport["$busy?"]()')
110
113
  end
@@ -127,12 +130,31 @@ module Isomorfeus
127
130
  global.Exception = e;
128
131
  }
129
132
  let application_state = global.Opal.Isomorfeus.store.native.getState();
130
- if (typeof global.Opal.Isomorfeus.Transport !== 'undefined') { global.Opal.Isomorfeus.Transport.$disconnect(); }
133
+ let transport_busy = false;
134
+ if (typeof global.Opal.Isomorfeus.Transport !== 'undefined' && global.Opal.Isomorfeus.Transport["$busy?"]()) { transport_busy = true; }
131
135
  if (typeof global.NanoCSSInstance !== 'undefined') { ssr_styles = global.NanoCSSInstance.raw }
132
- return [rendered_tree, application_state, ssr_styles, global.Opal.Isomorfeus['$ssr_response_status'](), global.Exception ? { message: global.Exception.message, stack: global.Exception.stack } : false];
136
+ return [rendered_tree, application_state, ssr_styles, global.Opal.Isomorfeus['$ssr_response_status'](), transport_busy, global.Exception ? { message: global.Exception.message, stack: global.Exception.stack } : false];
137
+ JAVASCRIPT
138
+ # execute further render passes
139
+ rendered_tree, application_state, @ssr_styles, @ssr_response_status, transport_busy, exception = Isomorfeus.ssr_contexts[thread_id_asset].exec(javascript)
140
+ break_while = false
141
+ start_time = Time.now
142
+ while transport_busy
143
+ break if (Time.now - start_time) > 5
144
+ while transport_busy
145
+ break if (Time.now - start_time) > 4
146
+ sleep 0.01
147
+ transport_busy = Isomorfeus.ssr_contexts[thread_id_asset].exec('return global.Opal.Isomorfeus.Transport["$busy?"]()')
148
+ end
149
+ # execute third render pass
150
+ pass += 1
151
+ rendered_tree, application_state, @ssr_styles, @ssr_response_status, transport_busy, exception = Isomorfeus.ssr_contexts[thread_id_asset].exec(javascript)
152
+ break if break_while || pass > 5
153
+ end
154
+ javascript = <<~JAVASCRIPT
155
+ if (typeof global.Opal.Isomorfeus.Transport !== 'undefined') { global.Opal.Isomorfeus.Transport.$disconnect(); }
133
156
  JAVASCRIPT
134
- # execute second render pass
135
- rendered_tree, application_state, @ssr_styles, @ssr_response_status, exception = Isomorfeus.ssr_contexts[thread_id_asset].exec(javascript)
157
+ Isomorfeus.ssr_contexts[thread_id_asset].exec(javascript)
136
158
  Isomorfeus.raise_error(message: exception['message'], stack: exception['stack']) if exception
137
159
  render_result << " data-iso-hydrated='true'" if rendered_tree
138
160
  if Isomorfeus.respond_to?(:current_user) && Isomorfeus.current_user && !Isomorfeus.current_user.anonymous?
@@ -150,6 +172,7 @@ module Isomorfeus
150
172
  if Isomorfeus.server_side_rendering
151
173
  render_result = "<script type='application/javascript'>\nServerSideRenderingStateJSON = #{Oj.dump(application_state, mode: :strict)}\n</script>\n" << render_result
152
174
  end
175
+ STDERR.puts "PreactViewHelper Server Side Rendering rendered #{pass} passes and took ~#{Time.now - start_time}s" if Isomorfeus.development?
153
176
  render_result
154
177
  end
155
178
 
@@ -33,10 +33,12 @@ module LucidApp
33
33
  var defined_refs = #{base.defined_refs};
34
34
  for (var ref in defined_refs) {
35
35
  if (defined_refs[ref] != null) {
36
- let r = ref; // to ensure cloure for function below gets correct ref name
36
+ let r = ref; // to ensure closure for function below gets correct ref name
37
37
  this[ref] = function(element) {
38
38
  element = oper.native_element_or_component_to_ruby(element);
39
+ oper.register_active_component(this);
39
40
  #{`this.__ruby_instance`.instance_exec(`element`, &`defined_refs[r]`)}
41
+ oper.unregister_active_component(this);
40
42
  }
41
43
  this[ref] = this[ref].bind(this);
42
44
  } else {
@@ -44,9 +46,9 @@ module LucidApp
44
46
  }
45
47
  }
46
48
  if (base.preload_block) {
47
- oper.active_redux_components.push(this);
49
+ oper.register_active_component(this);
48
50
  this.state.preloaded = this.__ruby_instance.$execute_preload_block();
49
- oper.active_redux_components.pop();
51
+ oper.unregister_active_component(this);
50
52
  }
51
53
  this.listener = this.listener.bind(this);
52
54
  this.unsubscriber = Opal.Isomorfeus.store.native.subscribe(this.listener);
@@ -57,17 +59,13 @@ module LucidApp
57
59
  render(props, state) {
58
60
  const oper = Opal.Preact;
59
61
  oper.render_buffer.push([]);
60
- // console.log("lucid app pushed", oper.render_buffer, oper.render_buffer.toString());
61
- oper.active_components.push(this);
62
- oper.active_redux_components.push(this);
62
+ oper.register_active_component(this);
63
63
  let block_result;
64
64
  if (base.while_loading_block && !state.preloaded) { block_result = #{`this.__ruby_instance`.instance_exec(&`base.while_loading_block`)}; }
65
65
  else { block_result = #{`this.__ruby_instance`.instance_exec(&`base.render_block`)}; }
66
66
  if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
67
- oper.active_redux_components.pop();
68
- oper.active_components.pop();
67
+ oper.unregister_active_component(this);
69
68
  let children = oper.render_buffer.pop();
70
- // console.log("lucid app popping", oper.render_buffer, oper.render_buffer.toString());
71
69
  return Opal.global.Preact.createElement(Opal.global.LucidApplicationContext.Provider, { value: { iso_store: this.state.isomorfeus_store_state, iso_theme: base.css_theme }}, children);
72
70
  }
73
71
  data_access() {
@@ -29,10 +29,12 @@ module LucidComponent
29
29
  var defined_refs = base.$defined_refs();
30
30
  for (var ref in defined_refs) {
31
31
  if (defined_refs[ref] != null) {
32
- let r = ref; // to ensure cloure for function below gets correct ref name
32
+ let r = ref; // to ensure closure for function below gets correct ref name
33
33
  this[ref] = function(element) {
34
34
  element = oper.native_element_or_component_to_ruby(element);
35
+ oper.register_active_component(this);
35
36
  #{`this.__ruby_instance`.instance_exec(`element`, &`defined_refs[r]`)}
37
+ oper.unregister_active_component(this);
36
38
  }
37
39
  this[ref] = this[ref].bind(this);
38
40
  } else {
@@ -40,9 +42,9 @@ module LucidComponent
40
42
  }
41
43
  }
42
44
  if (base.preload_block) {
43
- oper.active_redux_components.push(this);
45
+ oper.register_active_component(this);
44
46
  this.state.preloaded = this.__ruby_instance.$execute_preload_block();
45
- oper.active_redux_components.pop();
47
+ oper.unregister_active_component(this);
46
48
  }
47
49
  }
48
50
  static get displayName() {
@@ -51,16 +53,12 @@ module LucidComponent
51
53
  render(props, state) {
52
54
  const oper = Opal.Preact;
53
55
  oper.render_buffer.push([]);
54
- // console.log("lucid component pushed", oper.render_buffer, oper.render_buffer.toString());
55
- oper.active_components.push(this);
56
- oper.active_redux_components.push(this);
56
+ oper.register_active_component(this);
57
57
  let block_result;
58
58
  if (base.while_loading_block && !state.preloaded) { block_result = #{`this.__ruby_instance`.instance_exec(&`base.while_loading_block`)}; }
59
59
  else { block_result = #{`this.__ruby_instance`.instance_exec(&`base.render_block`)}; }
60
60
  if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
61
- oper.active_redux_components.pop();
62
- oper.active_components.pop();
63
- // console.log("lucid component popping", oper.render_buffer, oper.render_buffer.toString());
61
+ oper.unregister_active_component(this);
64
62
  let result = oper.render_buffer.pop();
65
63
  return (result.length === 1) ? result[0] : result;
66
64
  }
@@ -23,12 +23,10 @@ module LucidFunc
23
23
  const [__ruby_state, __ruby_dispatch] = og.PreactHooks.useReducer(base.instance_reducer, null, base.instance_init);
24
24
  const __ruby_instance = __ruby_state.instance;
25
25
  __ruby_instance.props = Object.assign({}, props, context);
26
- oper.active_components.push(__ruby_instance);
27
- oper.active_redux_components.push(__ruby_instance);
26
+ oper.register_active_component(__ruby_instance);
28
27
  let block_result = #{`__ruby_instance`.instance_exec(&`base.render_block`)};
29
28
  if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
30
- oper.active_redux_components.pop();
31
- oper.active_components.pop();
29
+ oper.unregister_active_component(__ruby_instance);
32
30
  // console.log("function popping", oper.render_buffer, oper.render_buffer.toString());
33
31
  let result = oper.render_buffer.pop();
34
32
  return (result.length === 1) ? result[0] : result;
@@ -13,15 +13,13 @@ module Preact
13
13
  base.preact_component = function(props) {
14
14
  const oper = Opal.Preact;
15
15
  oper.render_buffer.push([]);
16
- // console.log("function pushed", oper.render_buffer, oper.render_buffer.toString());
17
16
  const [__ruby_state, __ruby_dispatch] = Opal.global.PreactHooks.useReducer(base.instance_reducer, null, base.instance_init);
18
17
  const __ruby_instance = __ruby_state.instance;
19
18
  __ruby_instance.props = props;
20
- oper.active_components.push(__ruby_instance);
19
+ oper.register_active_component(__ruby_instance);
21
20
  let block_result = #{`__ruby_instance`.instance_exec(&`base.render_block`)};
22
21
  if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
23
- oper.active_components.pop();
24
- // console.log("function popping", oper.render_buffer, oper.render_buffer.toString());
22
+ oper.unregister_active_component(__ruby_instance);
25
23
  let result = oper.render_buffer.pop();
26
24
  return (result.length === 1) ? result[0] : result;
27
25
  }
@@ -7,9 +7,9 @@ module Preact
7
7
  # TODO convert error
8
8
  %x{
9
9
  var fun = function(error) {
10
- Opal.Preact.active_redux_components.push(this);
10
+ Opal.Preact.register_active_component(this);
11
11
  #{`this.__ruby_instance`.instance_exec(`error`, &block)};
12
- Opal.Preact.active_redux_components.pop();
12
+ Opal.Preact.unregister_active_component(this);
13
13
  }
14
14
  if (self.lucid_preact_component) { self.lucid_preact_component.prototype.componentDidCatch = fun; }
15
15
  else { self.preact_component.prototype.componentDidCatch = fun; }
@@ -19,9 +19,9 @@ module Preact
19
19
  def component_did_mount(&block)
20
20
  %x{
21
21
  let fun = function() {
22
- Opal.Preact.active_redux_components.push(this);
22
+ Opal.Preact.register_active_component(this);
23
23
  #{`this.__ruby_instance`.instance_exec(&block)};
24
- Opal.Preact.active_redux_components.pop();
24
+ Opal.Preact.unregister_active_component(this);
25
25
  }
26
26
  if (self.lucid_preact_component) {
27
27
  if (self.lucid_preact_component.prototype.componentDidMount) {
@@ -40,11 +40,11 @@ module Preact
40
40
  def component_did_update(&block)
41
41
  %x{
42
42
  var fun = function(prev_props, prev_state, snapshot) {
43
- Opal.Preact.active_redux_components.push(this);
43
+ Opal.Preact.register_active_component(this);
44
44
  #{`this.__ruby_instance`.instance_exec(`Opal.Preact.Props.$new({props: prev_props})`,
45
45
  `Opal.Preact.State.$new({state: prev_state})`,
46
46
  `snapshot`, &block)};
47
- Opal.Preact.active_redux_components.pop();
47
+ Opal.Preact.unregister_active_component(this);
48
48
  }
49
49
  if (self.lucid_preact_component) { self.lucid_preact_component.prototype.componentDidUpdate = fun; }
50
50
  else { self.preact_component.prototype.componentDidUpdate = fun; }
@@ -55,9 +55,9 @@ module Preact
55
55
  %x{
56
56
  var fun = function() {
57
57
  if (typeof this.unsubscriber === "function") { this.unsubscriber(); };
58
- Opal.Preact.active_redux_components.push(this);
58
+ Opal.Preact.register_active_component(this);
59
59
  #{`this.__ruby_instance`.instance_exec(&block)};
60
- Opal.Preact.active_redux_components.pop();
60
+ Opal.Preact.unregister_active_component(this);
61
61
  }
62
62
  if (self.lucid_preact_component) { self.lucid_preact_component.prototype.componentWillUnmount = fun; }
63
63
  else { self.preact_component.prototype.componentWillUnmount = fun; }
@@ -68,12 +68,12 @@ module Preact
68
68
  def get_derived_state_from_props(&block)
69
69
  %x{
70
70
  var fun = function(props, state) {
71
- Opal.Preact.active_redux_components.push(this);
71
+ Opal.Preact.register_active_component(this);
72
72
  var result = #{`this.__ruby_instance`.instance_exec(`Opal.Preact.Props.$new({props: props})`,
73
73
  `Opal.Preact.State.$new({state: state})`, &block)};
74
- Opal.Preact.active_redux_components.pop();
74
+ Opal.Preact.unregister_active_component(this);
75
75
  if (typeof result.$to_n === 'function') { result = result.$to_n() }
76
- if (result === Opal.nil) { return null; }
76
+ if (result === nil) { return null; }
77
77
  return result;
78
78
  }
79
79
  if (self.lucid_preact_component) { self.lucid_preact_component.prototype.getDerivedStateFromProps = fun; }
@@ -84,11 +84,11 @@ module Preact
84
84
  def get_snapshot_before_update(&block)
85
85
  %x{
86
86
  var fun = function(prev_props, prev_state) {
87
- Opal.Preact.active_redux_components.push(this);
87
+ Opal.Preact.register_active_component(this);
88
88
  var result = #{`this.__ruby_instance`.instance_exec(`Opal.Preact.Props.$new({props: prev_props})`,
89
89
  `Opal.Preact.State.$new({state: prev_state})`, &block)};
90
- Opal.Preact.active_redux_components.pop();
91
- if (result === Opal.nil) { return null; }
90
+ Opal.Preact.unregister_active_component(this);
91
+ if (result === nil) { return null; }
92
92
  return result;
93
93
  }
94
94
  if (self.lucid_preact_component) { self.lucid_preact_component.prototype.getSnapshotBeforeUpdate = fun; }
@@ -19,10 +19,13 @@ module Preact
19
19
  var defined_refs = #{base.defined_refs};
20
20
  for (var ref in defined_refs) {
21
21
  if (defined_refs[ref] != null) {
22
- let r = ref; // to ensure cloure for function below gets correct ref name
22
+ let r = ref; // to ensure closure for function below gets correct ref name
23
23
  this[ref] = function(element) {
24
- element = Opal.Preact.native_element_or_component_to_ruby(element);
24
+ const oper = Opal.Preact;
25
+ element = oper.native_element_or_component_to_ruby(element);
26
+ oper.register_active_component(this);
25
27
  #{`this.__ruby_instance`.instance_exec(`element`, &`defined_refs[r]`)}
28
+ oper.unregister_active_component(this);
26
29
  }
27
30
  this[ref] = this[ref].bind(this);
28
31
  } else {
@@ -36,21 +39,22 @@ module Preact
36
39
  render(props, state) {
37
40
  const oper = Opal.Preact;
38
41
  oper.render_buffer.push([]);
39
- // console.log("preact component pushed", oper.render_buffer, oper.render_buffer.toString());
40
- oper.active_components.push(this);
42
+ oper.register_active_component(this);
41
43
  let block_result = #{`this.__ruby_instance`.instance_exec(&`base.render_block`)};
42
44
  if (block_result && block_result !== nil) { oper.render_block_result(block_result); }
43
- // console.log("preact component popping", oper.render_buffer, oper.render_buffer.toString());
44
- oper.active_components.pop();
45
+ oper.unregister_active_component(this);
45
46
  let result = oper.render_buffer.pop();
46
47
  return (result.length === 1) ? result[0] : result;
47
48
  }
48
49
  shouldComponentUpdate(next_props, next_state) {
50
+ const oper = Opal.Preact;
49
51
  if (base.should_component_update_block) {
50
- return #{!!`this.__ruby_instance`.instance_exec(`Opal.Preact.Props.$new({props: next_props})`, `Opal.Preact.State.$new({state: next_state })`, &`base.should_component_update_block`)};
52
+ oper.register_active_component(this);
53
+ return #{!!`this.__ruby_instance`.instance_exec(`oper.Props.$new({props: next_props})`, `oper.State.$new({state: next_state })`, &`base.should_component_update_block`)};
54
+ oper.unregister_active_component(this);
51
55
  }
52
- if (!Opal.Preact.props_are_equal(this.props, next_props)) { return true; }
53
- if (Opal.Preact.state_is_not_equal(this.state, next_state)) { return true; }
56
+ if (!oper.props_are_equal(this.props, next_props)) { return true; }
57
+ if (oper.state_is_not_equal(this.state, next_state)) { return true; }
54
58
  return false;
55
59
  }
56
60
  validateProp(props, propName, componentName) {
@@ -1,3 +1,3 @@
1
1
  module Preact
2
- VERSION = '10.6.20'
2
+ VERSION = '10.6.24'
3
3
  end
data/lib/preact.rb CHANGED
@@ -96,6 +96,20 @@ module Preact
96
96
  return self.active_redux_components[length-1];
97
97
  };
98
98
 
99
+ self.register_active_component = function(component) {
100
+ self.active_components.push(component);
101
+ if (typeof(component.data_access) === 'function') {
102
+ self.active_redux_components.push(component);
103
+ }
104
+ };
105
+
106
+ self.unregister_active_component = function(component) {
107
+ if (typeof(component.data_access) === 'function') {
108
+ self.active_redux_components.pop();
109
+ }
110
+ self.active_components.pop();
111
+ };
112
+
99
113
  function isObject(obj) { return (obj && typeof obj === 'object'); }
100
114
 
101
115
  self.merge_deep = function(one, two) {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isomorfeus-preact
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.6.20
4
+ version: 10.6.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-29 00:00:00.000000000 Z
11
+ date: 2022-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.14.7
89
+ version: 0.14.8
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.14.7
96
+ version: 0.14.8
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: isomorfeus-redux
99
99
  requirement: !ruby/object:Gem::Requirement