19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
# File 'lib/isomorfeus/preact_view_helper.rb', line 19
def mount_component(component_name, props = {}, asset_key = 'ssr.js', skip_ssr: false, use_ssr: false, max_passes: 4)
ssr_start_time = Time.now if Isomorfeus.development?
@ssr_response_status = nil
@ssr_styles = nil
render_result = "<div data-iso-env=\"#{Isomorfeus.env}\" data-iso-root=\"#{component_name}\" data-iso-props='#{Oj.dump(props, mode: :strict)}'"
if !skip_ssr && (Isomorfeus.server_side_rendering || use_ssr)
thread_id_asset = "#{Thread.current.object_id}|#{asset_key}"
begin
init_speednode_context(asset_key, thread_id_asset) if Isomorfeus.development? || !Isomorfeus.ssr_contexts.key?(thread_id_asset)
rescue Exception => e
Isomorfeus.raise_error(message: "Server Side Rendering: Failed creating context for #{asset_key}. Error: #{e.message}", stack: e.backtrace)
end
ctx = Isomorfeus.ssr_contexts[thread_id_asset]
pass = 0
ws_scheme = props[:location_scheme] == 'https:' ? 'wss:' : 'ws:'
location_host = props[:location_host] ? props[:location_host] : 'localhost'
api_ws_path = Isomorfeus.respond_to?(:api_websocket_path) ? Isomorfeus.api_websocket_path : ''
transport_ws_url = ws_scheme + location_host + api_ws_path
javascript = " return Opal.Isomorfeus.SSR.mount_component('\#{Thread.current[:isomorfeus_session_id]}', '\#{Isomorfeus.env}', '\#{props[:locale]}', '\#{transport_ws_url}', '\#{component_name}', \#{Oj.dump(props, mode: :strict)}, \#{max_passes})\n JAVASCRIPT\n\n begin\n ctx.exec(javascript)\n rescue Exception => e\n Isomorfeus.raise_error(error: e)\n end\n\n sleep 0.001 # give other threads that would respond to a request from node/SSR a chance to run\n rendering = ctx.eval_script(key: :rendering)\n if rendering\n start_time = Time.now\n while rendering\n break if (Time.now - start_time) > 10\n sleep 0.005\n rendering = ctx.eval_script(key: :rendering)\n end\n end\n\n rendered_tree, application_state, @ssr_styles, @ssr_response_status, passes, exception = ctx.eval_script(key: :get_result)\n Isomorfeus.raise_error(message: \"Server Side Rendering: \#{exception['message']}\", stack: exception['stack']) if exception\n\n render_result << \" data-iso-hydrated='true'\" if rendered_tree\n if Isomorfeus.respond_to?(:current_user) && Isomorfeus.current_user && !Isomorfeus.current_user.anonymous?\n render_result << \" data-iso-usid=\#{Oj.dump(Isomorfeus.current_user.sid, mode: :strict)}\"\n end\n render_result << \" data-iso-nloc='\#{props[:locale]}'>\"\n render_result << (rendered_tree ? rendered_tree : \"SSR didn't work\")\n else\n if Isomorfeus.respond_to?(:current_user) && Isomorfeus.current_user && !Isomorfeus.current_user.anonymous?\n render_result << \" data-iso-usid=\#{Oj.dump(Isomorfeus.current_user.sid, mode: :strict)}\"\n end\n render_result << \" data-iso-nloc='\#{props[:locale]}'>\"\n end\n render_result << '</div>'\n if Isomorfeus.server_side_rendering && !skip_ssr\n render_result = \"<script type='application/javascript'>\\nServerSideRenderingStateJSON = \#{Oj.dump(application_state, mode: :strict)}\\n</script>\\n\" << render_result\n puts \"PreactViewHelper Server Side Rendering rendered \#{passes} passes and took ~\#{((Time.now - ssr_start_time)*1000).to_i}ms\" if Isomorfeus.development?\n end\n render_result\nend\n"
|