isomorfeus-preact 10.6.36 → 10.6.37
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 +4 -4
- data/lib/isomorfeus/preact/config.rb +1 -1
- data/lib/isomorfeus/preact_view_helper.rb +91 -99
- data/lib/isomorfeus/ssr.rb +75 -0
- data/lib/isomorfeus/top_level.rb +2 -24
- data/lib/isomorfeus/top_level_ssr.rb +23 -0
- data/lib/isomorfeus-preact.rb +1 -0
- data/lib/preact/version.rb +1 -1
- data/lib/preact.rb +4 -3
- metadata +10 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f82bf99a53bc67d3fd34a366579d35c1e560c6dd860e9981dca3c24e58a4bed6
|
|
4
|
+
data.tar.gz: c031adbcb8102d1225012d1526e602b70275b872be1b74c96828c1e53c20c78d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c238454b703626f7db793109fe26c81443e55ffe6bae3e0a717132369bcdb8854c5319bc56db2780f976b4721e1e0f26bd07ddb21cddcb04fe0d8a15bc63e4cf
|
|
7
|
+
data.tar.gz: 28b3a937f2e305534e7cfc038de0f76445128b58c464d6596b5de36e79d3f25f709956d34969f8e681d3780c0d2fe9e4a07d672005aba5cc205c9ab477493e15
|
|
@@ -17,19 +17,13 @@ module Isomorfeus
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def mount_component(component_name, props = {}, asset_key = 'ssr.js', skip_ssr: false, use_ssr: false, max_passes: 4)
|
|
20
|
+
ssr_start_time = Time.now if Isomorfeus.development?
|
|
20
21
|
@ssr_response_status = nil
|
|
21
22
|
@ssr_styles = nil
|
|
22
|
-
thread_id_asset = "#{Thread.current.object_id}#{asset_key}"
|
|
23
23
|
render_result = "<div data-iso-env=\"#{Isomorfeus.env}\" data-iso-root=\"#{component_name}\" data-iso-props='#{Oj.dump(props, mode: :strict)}'"
|
|
24
24
|
if !skip_ssr && (Isomorfeus.server_side_rendering || use_ssr)
|
|
25
|
+
thread_id_asset = "#{Thread.current.object_id}#{asset_key}"
|
|
25
26
|
if Isomorfeus.development?
|
|
26
|
-
# always create a new context, effectively reloading code
|
|
27
|
-
# delete the existing context first, saves memory
|
|
28
|
-
if Isomorfeus.ssr_contexts.key?(thread_id_asset)
|
|
29
|
-
uuid = Isomorfeus.ssr_contexts[thread_id_asset].instance_variable_get(:@uuid)
|
|
30
|
-
runtime = Isomorfeus.ssr_contexts[thread_id_asset].instance_variable_get(:@runtime)
|
|
31
|
-
runtime.vm.delete_context(uuid)
|
|
32
|
-
end
|
|
33
27
|
begin
|
|
34
28
|
init_speednode_context(asset_key, thread_id_asset)
|
|
35
29
|
rescue Exception => e
|
|
@@ -41,7 +35,7 @@ module Isomorfeus
|
|
|
41
35
|
end
|
|
42
36
|
end
|
|
43
37
|
|
|
44
|
-
|
|
38
|
+
ctx = Isomorfeus.ssr_contexts[thread_id_asset]
|
|
45
39
|
pass = 0
|
|
46
40
|
# if location_host and scheme are given and if Transport is loaded, connect and then render,
|
|
47
41
|
# otherwise do not render because only one pass is required
|
|
@@ -53,110 +47,84 @@ module Isomorfeus
|
|
|
53
47
|
# build javascript for rendering first pass
|
|
54
48
|
# it will initialize buffers to guard against leaks, maybe caused by previous exceptions
|
|
55
49
|
javascript = <<~JAVASCRIPT
|
|
56
|
-
|
|
57
|
-
global.Opal.Preact.active_components = [];
|
|
58
|
-
global.Opal.Preact.active_redux_components = [];
|
|
59
|
-
global.FirstPassFinished = false;
|
|
60
|
-
global.Exception = false;
|
|
61
|
-
global.IsomorfeusSessionId = '#{Thread.current[:isomorfeus_session_id]}';
|
|
62
|
-
global.Opal.Isomorfeus['$env=']('#{Isomorfeus.env}');
|
|
63
|
-
if (typeof global.Opal.Isomorfeus["$current_locale="] === 'function') {
|
|
64
|
-
global.Opal.Isomorfeus["$current_locale="]('#{props[:locale]}');
|
|
65
|
-
} else if (typeof global.Opal.Isomorfeus["$negotiated_locale="] === 'function') { // remove later on
|
|
66
|
-
global.Opal.Isomorfeus["$negotiated_locale="]('#{props[:locale]}');
|
|
67
|
-
}
|
|
68
|
-
global.Opal.Isomorfeus['$force_init!']();
|
|
69
|
-
global.Opal.Isomorfeus['$ssr_response_status='](200);
|
|
70
|
-
global.Opal.Isomorfeus.TopLevel['$ssr_route_path=']('#{props[:location]}');
|
|
71
|
-
let api_ws_path = '#{api_ws_path}';
|
|
72
|
-
let exception;
|
|
73
|
-
if (typeof global.Opal.Isomorfeus.Transport !== 'undefined' && api_ws_path !== '') {
|
|
74
|
-
global.Opal.Isomorfeus.TopLevel["$transport_ws_url="]("#{transport_ws_url}");
|
|
75
|
-
global.Opal.send(global.Opal.Isomorfeus.Transport.$promise_connect(global.IsomorfeusSessionId), 'then', [], ($$1 = function(){
|
|
76
|
-
try {
|
|
77
|
-
global.Opal.Isomorfeus.TopLevel.$render_component_to_string('#{component_name}', #{Oj.dump(props, mode: :strict)});
|
|
78
|
-
global.FirstPassFinished = 'transport';
|
|
79
|
-
} catch (e) {
|
|
80
|
-
global.Exception = e;
|
|
81
|
-
global.FirstPassFinished = 'transport';
|
|
82
|
-
}
|
|
83
|
-
}, $$1.$$s = this, $$1.$$arity = 0, $$1))
|
|
84
|
-
return false;
|
|
85
|
-
} else { global.FirstPassFinished = true; return true; };
|
|
50
|
+
return Opal.Isomorfeus.SSR.first_pass('#{Thread.current[:isomorfeus_session_id]}', '#{Isomorfeus.env}', '#{props[:locale]}', '#{props[:location]}', '#{api_ws_path}', '#{transport_ws_url}', '#{component_name}', #{Oj.dump(props, mode: :strict)})
|
|
86
51
|
JAVASCRIPT
|
|
52
|
+
|
|
53
|
+
finished = false
|
|
87
54
|
# execute first render pass
|
|
88
55
|
begin
|
|
89
|
-
|
|
56
|
+
pass += 1
|
|
57
|
+
has_transport, has_store, need_further_pass, exception = ctx.exec(javascript)
|
|
58
|
+
Isomorfeus.raise_error(message: "Server Side Rendering: #{exception['message']}", stack: exception['stack']) if exception
|
|
90
59
|
rescue Exception => e
|
|
91
60
|
Isomorfeus.raise_error(error: e)
|
|
92
61
|
end
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
pass
|
|
96
|
-
first_pass_finished, exception =
|
|
62
|
+
|
|
63
|
+
if has_transport
|
|
64
|
+
# wait for first pass to finish
|
|
65
|
+
first_pass_finished, need_further_pass, exception = ctx.eval_script(key: :first_pass_check)
|
|
97
66
|
Isomorfeus.raise_error(message: "Server Side Rendering: #{exception['message']}", stack: exception['stack']) if exception
|
|
98
67
|
unless first_pass_finished
|
|
99
68
|
start_time = Time.now
|
|
100
69
|
while !first_pass_finished
|
|
101
70
|
break if (Time.now - start_time) > 10
|
|
102
|
-
sleep 0.
|
|
103
|
-
first_pass_finished =
|
|
71
|
+
sleep 0.005
|
|
72
|
+
first_pass_finished, need_further_pass, exception = ctx.eval_script(key: :first_pass_check)
|
|
73
|
+
Isomorfeus.raise_error(message: "Server Side Rendering: #{exception['message']}", stack: exception['stack']) if exception
|
|
104
74
|
end
|
|
105
75
|
end
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
end
|
|
76
|
+
|
|
77
|
+
# wait for transport to settle
|
|
78
|
+
transport_busy = ctx.eval_script(key: :transport_busy)
|
|
79
|
+
if transport_busy
|
|
80
|
+
start_time = Time.now
|
|
81
|
+
while transport_busy
|
|
82
|
+
break if (Time.now - start_time) > 5
|
|
83
|
+
sleep 0.005
|
|
84
|
+
transport_busy = ctx.eval_script(key: :transport_busy)
|
|
116
85
|
end
|
|
117
86
|
end
|
|
118
87
|
end
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
88
|
+
|
|
89
|
+
if !need_further_pass
|
|
90
|
+
rendered_tree, application_state, @ssr_styles, @ssr_response_status, exception = ctx.eval_script(key: :first_pass_result)
|
|
91
|
+
Isomorfeus.raise_error(message: "Server Side Rendering: #{exception['message']}", stack: exception['stack']) if exception
|
|
92
|
+
else
|
|
93
|
+
start_time = Time.now
|
|
94
|
+
script_key = if has_transport && has_store
|
|
95
|
+
:sill_busy
|
|
96
|
+
elsif has_transport
|
|
97
|
+
:transport_busy
|
|
98
|
+
elsif has_store
|
|
99
|
+
:store_busy
|
|
100
|
+
else
|
|
101
|
+
nil
|
|
102
|
+
end
|
|
103
|
+
while need_further_pass
|
|
104
|
+
# execute further render passes
|
|
105
|
+
javascript = <<~JAVASCRIPT
|
|
106
|
+
return Opal.Isomorfeus.SSR.further_pass('#{component_name}', #{Oj.dump(props, mode: :strict)})
|
|
107
|
+
JAVASCRIPT
|
|
108
|
+
pass += 1
|
|
109
|
+
rendered_tree, application_state, @ssr_styles, @ssr_response_status, need_further_pass, exception = ctx.exec(javascript)
|
|
110
|
+
Isomorfeus.raise_error(message: "Server Side Rendering: #{exception['message']}", stack: exception['stack']) if exception
|
|
111
|
+
if need_further_pass && script_key
|
|
112
|
+
break if (Time.now - start_time) > 5
|
|
113
|
+
need_further_pass = ctx.eval_script(key: script_key)
|
|
114
|
+
while need_further_pass
|
|
115
|
+
break if (Time.now - start_time) > 4
|
|
116
|
+
sleep 0.01
|
|
117
|
+
need_further_pass = ctx.eval_script(key: script_key)
|
|
118
|
+
end
|
|
119
|
+
break if pass >= max_passes
|
|
120
|
+
else
|
|
121
|
+
break
|
|
122
|
+
end
|
|
150
123
|
end
|
|
151
|
-
pass += 1
|
|
152
|
-
rendered_tree, application_state, @ssr_styles, @ssr_response_status, still_busy, exception = Isomorfeus.ssr_contexts[thread_id_asset].exec(javascript)
|
|
153
|
-
break if pass >= max_passes
|
|
154
124
|
end
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
Isomorfeus.ssr_contexts[thread_id_asset].exec(javascript)
|
|
159
|
-
Isomorfeus.raise_error(message: exception['message'], stack: exception['stack']) if exception
|
|
125
|
+
|
|
126
|
+
ctx.eval_script(key: :transport_disconnect) if has_transport
|
|
127
|
+
|
|
160
128
|
render_result << " data-iso-hydrated='true'" if rendered_tree
|
|
161
129
|
if Isomorfeus.respond_to?(:current_user) && Isomorfeus.current_user && !Isomorfeus.current_user.anonymous?
|
|
162
130
|
render_result << " data-iso-usid=#{Oj.dump(Isomorfeus.current_user.sid, mode: :strict)}"
|
|
@@ -170,10 +138,10 @@ module Isomorfeus
|
|
|
170
138
|
render_result << " data-iso-nloc='#{props[:locale]}'>"
|
|
171
139
|
end
|
|
172
140
|
render_result << '</div>'
|
|
173
|
-
if Isomorfeus.server_side_rendering
|
|
141
|
+
if Isomorfeus.server_side_rendering && !skip_ssr
|
|
174
142
|
render_result = "<script type='application/javascript'>\nServerSideRenderingStateJSON = #{Oj.dump(application_state, mode: :strict)}\n</script>\n" << render_result
|
|
143
|
+
puts "PreactViewHelper Server Side Rendering rendered #{pass} passes and took ~#{((Time.now - ssr_start_time)*1000).to_i}ms" if Isomorfeus.development?
|
|
175
144
|
end
|
|
176
|
-
STDERR.puts "PreactViewHelper Server Side Rendering rendered #{pass} passes and took ~#{((Time.now - start_time)*1000).to_i}ms" if Isomorfeus.development? && !skip_ssr
|
|
177
145
|
render_result
|
|
178
146
|
end
|
|
179
147
|
|
|
@@ -198,8 +166,32 @@ module Isomorfeus
|
|
|
198
166
|
def init_speednode_context(asset_key, thread_id_asset)
|
|
199
167
|
asset = Isomorfeus.assets[asset_key]
|
|
200
168
|
raise "#{self.class.name}: Asset not found: #{asset_key}" unless asset
|
|
201
|
-
|
|
202
|
-
|
|
169
|
+
if !Isomorfeus.ssr_contexts.key?(thread_id_asset) || !asset.bundled?
|
|
170
|
+
if Isomorfeus.ssr_contexts.key?(thread_id_asset)
|
|
171
|
+
uuid = Isomorfeus.ssr_contexts[thread_id_asset].instance_variable_get(:@uuid)
|
|
172
|
+
runtime = Isomorfeus.ssr_contexts[thread_id_asset].instance_variable_get(:@runtime)
|
|
173
|
+
runtime.vm.delete_context(uuid)
|
|
174
|
+
end
|
|
175
|
+
asset_manager.transition(asset_key, asset)
|
|
176
|
+
Isomorfeus.ssr_contexts[thread_id_asset] = ExecJS.permissive_compile(asset.bundle)
|
|
177
|
+
ctx = Isomorfeus.ssr_contexts[thread_id_asset]
|
|
178
|
+
ctx.exec(top_level_mod)
|
|
179
|
+
ctx.exec(ssr_mod)
|
|
180
|
+
ctx.add_script(key: :first_pass_check, source: '[global.FirstPassFinished, global.NeedFurtherPass, global.Exception ? { message: global.Exception.message, stack: global.Exception.stack } : false ]')
|
|
181
|
+
ctx.add_script(key: :first_pass_result, source: 'Opal.Isomorfeus.SSR.first_pass_result()')
|
|
182
|
+
ctx.add_script(key: :still_busy, source: 'let nfp = global.Opal.Isomorfeus.Transport["$busy?"]() || global.Opal.Isomorfeus.store["$recently_dispatched?"](); (nfp == nil) ? false : nfp;')
|
|
183
|
+
ctx.add_script(key: :store_busy, source: 'let nfp = global.Opal.Isomorfeus.store["$recently_dispatched?"](); (nfp == nil) ? false : nfp;')
|
|
184
|
+
ctx.add_script(key: :transport_busy, source: 'global.Opal.Isomorfeus.Transport["$busy?"]()')
|
|
185
|
+
ctx.add_script(key: :transport_disconnect, source: 'global.Opal.Isomorfeus.Transport.$disconnect()')
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def ssr_mod
|
|
190
|
+
@_ssr_mod ||= Opal.compile(File.read(File.expand_path(File.join(File.dirname(__FILE__), 'ssr.rb'))))
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def top_level_mod
|
|
194
|
+
@_top_level_mod ||= Opal.compile(File.read(File.expand_path(File.join(File.dirname(__FILE__), 'top_level_ssr.rb'))))
|
|
203
195
|
end
|
|
204
196
|
end
|
|
205
197
|
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module Isomorfeus
|
|
2
|
+
module SSR
|
|
3
|
+
%x{
|
|
4
|
+
self.first_pass = function(session_id, env, locale, location, api_ws_path, transport_ws_url, component_name, props) {
|
|
5
|
+
global.Opal.Preact.render_buffer = [];
|
|
6
|
+
global.Opal.Preact.active_components = [];
|
|
7
|
+
global.Opal.Preact.active_redux_components = [];
|
|
8
|
+
global.FirstPassFinished = false;
|
|
9
|
+
global.NeedFurtherPass = false;
|
|
10
|
+
global.RenderedTree = '';
|
|
11
|
+
global.Exception = false;
|
|
12
|
+
global.IsomorfeusSessionId = session_id;
|
|
13
|
+
global.HasTransport = (typeof global.Opal.Isomorfeus.Transport !== 'undefined') && (api_ws_path !== '');
|
|
14
|
+
global.HasStore = typeof global.Opal.Isomorfeus.store !== 'undefined';
|
|
15
|
+
global.Opal.Isomorfeus['$env='](env);
|
|
16
|
+
if (typeof global.Opal.Isomorfeus["$current_locale="] === 'function') { global.Opal.Isomorfeus["$current_locale="](''); }
|
|
17
|
+
global.Opal.Isomorfeus['$force_init!']();
|
|
18
|
+
global.Opal.Isomorfeus['$ssr_response_status='](200);
|
|
19
|
+
global.Opal.Isomorfeus.TopLevel['$ssr_route_path='](location);
|
|
20
|
+
if (global.HasTransport) {
|
|
21
|
+
global.Opal.Isomorfeus.TopLevel["$transport_ws_url="](transport_ws_url);
|
|
22
|
+
global.Opal.send(global.Opal.Isomorfeus.Transport.$promise_connect(global.IsomorfeusSessionId), 'then', [], ($$1 = function(){
|
|
23
|
+
try {
|
|
24
|
+
global.RenderedTree = global.Opal.Isomorfeus.TopLevel.$render_component_to_string(component_name, props);
|
|
25
|
+
let nfp = global.Opal.Isomorfeus.Transport["$busy?"]() || global.Opal.Isomorfeus.store['$recently_dispatched?']();
|
|
26
|
+
global.NeedFurtherPass = (nfp == nil) ? false : nfp;
|
|
27
|
+
global.FirstPassFinished = false;
|
|
28
|
+
} catch (e) {
|
|
29
|
+
global.Exception = e;
|
|
30
|
+
global.NeedFurtherPass = false;
|
|
31
|
+
}
|
|
32
|
+
}, $$1.$$s = this, $$1.$$arity = 0, $$1))
|
|
33
|
+
} else {
|
|
34
|
+
try {
|
|
35
|
+
global.RenderedTree = global.Opal.Isomorfeus.TopLevel.$render_component_to_string(component_name, props);
|
|
36
|
+
if (global.HasStore) {
|
|
37
|
+
let nfp = global.Opal.Isomorfeus.store['$recently_dispatched?']();
|
|
38
|
+
global.NeedFurtherPass = (nfp == nil) ? false : nfp;
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {
|
|
41
|
+
global.Exception = e;
|
|
42
|
+
global.NeedFurtherPass = false;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return [global.HasTransport, global.HasStore, global.NeedFurtherPass, global.Exception ? { message: global.Exception.message, stack: global.Exception.stack } : false];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
self.first_pass_result = function() {
|
|
49
|
+
let ssr_styles;
|
|
50
|
+
let application_state = global.Opal.Isomorfeus.store.native.getState();
|
|
51
|
+
if (typeof global.NanoCSSInstance !== 'undefined') { ssr_styles = global.NanoCSSInstance.raw }
|
|
52
|
+
return [global.RenderedTree, application_state, ssr_styles, global.Opal.Isomorfeus['$ssr_response_status'](), global.Exception ? { message: global.Exception.message, stack: global.Exception.stack } : false];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
self.further_pass = function(component_name, props) {
|
|
56
|
+
global.Opal.Preact.render_buffer = [];
|
|
57
|
+
global.Opal.Preact.active_components = [];
|
|
58
|
+
global.Opal.Preact.active_redux_components = [];
|
|
59
|
+
global.Exception = false;
|
|
60
|
+
let rendered_tree;
|
|
61
|
+
let ssr_styles;
|
|
62
|
+
try {
|
|
63
|
+
rendered_tree = global.Opal.Isomorfeus.TopLevel.$render_component_to_string(component_name, props);
|
|
64
|
+
} catch (e) {
|
|
65
|
+
global.Exception = e;
|
|
66
|
+
}
|
|
67
|
+
let application_state = global.Opal.Isomorfeus.store.native.getState();
|
|
68
|
+
if (typeof global.NanoCSSInstance !== 'undefined') { ssr_styles = global.NanoCSSInstance.raw }
|
|
69
|
+
let nfp = (global.HasTransport && global.Opal.Isomorfeus.Transport["$busy?"]()) || (global.HasStore && global.Opal.Isomorfeus.store["$recently_dispatched?"]());
|
|
70
|
+
global.NeedFurtherPass = (nfp == nil) ? false : nfp;
|
|
71
|
+
return [rendered_tree, application_state, ssr_styles, global.Opal.Isomorfeus['$ssr_response_status'](), global.NeedFurtherPass, global.Exception ? { message: global.Exception.message, stack: global.Exception.stack } : false];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
end
|
data/lib/isomorfeus/top_level.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Isomorfeus
|
|
2
2
|
class TopLevel
|
|
3
3
|
class << self
|
|
4
|
-
if on_browser?
|
|
4
|
+
if on_browser?
|
|
5
5
|
def mount!
|
|
6
6
|
Isomorfeus.init
|
|
7
7
|
Isomorfeus::TopLevel.on_ready do
|
|
@@ -94,29 +94,7 @@ module Isomorfeus
|
|
|
94
94
|
hydrated ? Preact.hydrate(top, element) : Preact.render(top, element)
|
|
95
95
|
Isomorfeus.top_component = top
|
|
96
96
|
end
|
|
97
|
-
|
|
98
|
-
attr_accessor :ssr_route_path
|
|
99
|
-
attr_accessor :transport_ws_url
|
|
100
|
-
|
|
101
|
-
def mount!
|
|
102
|
-
# nothing, but keep it for compatibility with browser
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def render_component_to_string(component_name, props)
|
|
106
|
-
component = nil
|
|
107
|
-
%x{
|
|
108
|
-
if (typeof component_name === 'string' || component_name instanceof String) {
|
|
109
|
-
component = component_name.split(".").reduce(function(o, x) {
|
|
110
|
-
return (o !== null && typeof o[x] !== "undefined" && o[x] !== null) ? o[x] : null;
|
|
111
|
-
}, Opal.global)
|
|
112
|
-
} else {
|
|
113
|
-
component = component_name;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
component = Isomorfeus.cached_component_class(component_name) unless component
|
|
117
|
-
Preact.render_to_string(Preact.create_element(component, `Opal.Hash.$new(props)`))
|
|
118
|
-
end
|
|
119
|
-
end # execution environment
|
|
97
|
+
end
|
|
120
98
|
end
|
|
121
99
|
end
|
|
122
100
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Isomorfeus
|
|
2
|
+
class TopLevel
|
|
3
|
+
class << self
|
|
4
|
+
attr_accessor :ssr_route_path
|
|
5
|
+
attr_accessor :transport_ws_url
|
|
6
|
+
|
|
7
|
+
def render_component_to_string(component_name, props)
|
|
8
|
+
component = nil
|
|
9
|
+
%x{
|
|
10
|
+
if (typeof component_name === 'string' || component_name instanceof String) {
|
|
11
|
+
component = component_name.split(".").reduce(function(o, x) {
|
|
12
|
+
return (o !== null && typeof o[x] !== "undefined" && o[x] !== null) ? o[x] : null;
|
|
13
|
+
}, Opal.global)
|
|
14
|
+
} else {
|
|
15
|
+
component = component_name;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
component = Isomorfeus.cached_component_class(component_name) unless component
|
|
19
|
+
Preact.render_to_string(Preact.create_element(component, `Opal.Hash.$new(props)`))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/isomorfeus-preact.rb
CHANGED
data/lib/preact/version.rb
CHANGED
data/lib/preact.rb
CHANGED
|
@@ -196,11 +196,12 @@ module Preact
|
|
|
196
196
|
};
|
|
197
197
|
|
|
198
198
|
self.internal_render = function(component, props, string_child, block) {
|
|
199
|
+
const oper = Opal.global.Preact;
|
|
199
200
|
const operabu = self.render_buffer;
|
|
200
201
|
let native_props;
|
|
201
202
|
if (props && props !== nil) { native_props = self.to_native_preact_props(props); }
|
|
202
203
|
if (string_child) {
|
|
203
|
-
operabu[operabu.length - 1].push(
|
|
204
|
+
operabu[operabu.length - 1].push(oper.createElement(component, native_props, string_child));
|
|
204
205
|
} else if (block && block !== nil) {
|
|
205
206
|
operabu.push([]);
|
|
206
207
|
// console.log("internal_render pushed", Opal.Preact.render_buffer, Opal.Preact.render_buffer.toString());
|
|
@@ -208,9 +209,9 @@ module Preact
|
|
|
208
209
|
if (block_result && block_result !== nil) { Opal.Preact.render_block_result(block_result); }
|
|
209
210
|
// console.log("internal_render popping", Opal.Preact.render_buffer, Opal.Preact.render_buffer.toString());
|
|
210
211
|
let children = operabu.pop();
|
|
211
|
-
operabu[operabu.length - 1].push(
|
|
212
|
+
operabu[operabu.length - 1].push(oper.createElement.apply(this, [component, native_props].concat(children)));
|
|
212
213
|
} else {
|
|
213
|
-
operabu[operabu.length - 1].push(
|
|
214
|
+
operabu[operabu.length - 1].push(oper.createElement(component, native_props));
|
|
214
215
|
}
|
|
215
216
|
};
|
|
216
217
|
|
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.
|
|
4
|
+
version: 10.6.37
|
|
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-02-
|
|
11
|
+
date: 2022-02-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -86,42 +86,42 @@ dependencies:
|
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 0.14.
|
|
89
|
+
version: 0.14.14
|
|
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.
|
|
96
|
+
version: 0.14.14
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: isomorfeus-redux
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
101
|
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 4.1.
|
|
103
|
+
version: 4.1.18
|
|
104
104
|
type: :runtime
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 4.1.
|
|
110
|
+
version: 4.1.18
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: isomorfeus-speednode
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
115
|
- - "~>"
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 0.
|
|
117
|
+
version: 0.5.2
|
|
118
118
|
type: :runtime
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 0.
|
|
124
|
+
version: 0.5.2
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: dalli
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -232,7 +232,9 @@ files:
|
|
|
232
232
|
- lib/isomorfeus/preact_view_helper.rb
|
|
233
233
|
- lib/isomorfeus/props/validate_hash_proxy.rb
|
|
234
234
|
- lib/isomorfeus/props/validator.rb
|
|
235
|
+
- lib/isomorfeus/ssr.rb
|
|
235
236
|
- lib/isomorfeus/top_level.rb
|
|
237
|
+
- lib/isomorfeus/top_level_ssr.rb
|
|
236
238
|
- lib/isomorfeus_preact/lucid_app/api.rb
|
|
237
239
|
- lib/isomorfeus_preact/lucid_app/base.rb
|
|
238
240
|
- lib/isomorfeus_preact/lucid_app/mixin.rb
|