Class: ReactOnRailsPro::ServerRenderingPool::NodeRenderingPool

Inherits:
Object
  • Object
show all
Includes:
ScoutApm::Tracer
Defined in:
lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb

Overview

This implementation of the rendering pool uses NodeJS to execute javasript code

Constant Summary collapse

RENDERED_HTML_KEY =
"renderedHtml"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.bundle_hashObject (readonly)

Returns the value of attribute bundle_hash.



10
11
12
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 10

def bundle_hash
  @bundle_hash
end

Class Method Details

.eval_js(js_code, render_options, send_bundle: false) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 78

def eval_js(js_code, render_options, send_bundle: false)
  path = prepare_render_path(js_code, render_options)

  response = ReactOnRailsPro::Request.render_code(path, js_code, send_bundle)

  case response.status
  when 200
    response.body
  when ReactOnRailsPro::STATUS_SEND_BUNDLE
    # To prevent infinite loop
    ReactOnRailsPro::Error.raise_duplicate_bundle_upload_error if send_bundle

    eval_js(js_code, render_options, send_bundle: true)
  when ReactOnRailsPro::STATUS_BAD_REQUEST
    raise ReactOnRailsPro::Error,
          "Renderer rejected malformed request or hit an unhandled VM error: " \
          "#{response.status}:\n#{response.body}"
  else
    raise ReactOnRailsPro::Error,
          "Unexpected response code from renderer: #{response.status}:\n#{response.body}"
  end
rescue StandardError => e
  raise e unless ReactOnRailsPro.configuration.renderer_use_fallback_exec_js

  fallback_exec_js(js_code, render_options, e)
end

.eval_streaming_js(js_code, render_options) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 55

def eval_streaming_js(js_code, render_options)
  is_rsc_payload = ReactOnRailsPro.configuration.enable_rsc_support && render_options.rsc_payload_streaming?
  async_props_block = render_options.internal_option(:async_props_block)

  if async_props_block
    # Use incremental rendering when async props block is provided
    path = prepare_incremental_render_path(js_code, render_options)
    ReactOnRailsPro::Request.render_code_with_incremental_updates(
      path,
      js_code,
      async_props_block: async_props_block
    )
  else
    # Use standard streaming when no async props block
    path = prepare_render_path(js_code, render_options)
    ReactOnRailsPro::Request.render_code_as_stream(
      path,
      js_code,
      is_rsc_payload: is_rsc_payload
    )
  end
end

.exec_server_render_js(js_code, render_options) ⇒ Object

js_code: JavaScript expression that returns a string. Returns a Hash:

html: string of HTML for direct insertion on the page by evaluating js_code
consoleReplayScript: script for replaying console
hasErrors: true if server rendering errors

Note, js_code does not have to be based on React. js_code MUST RETURN json stringify Object Calling code will probably call ‘html_safe’ on return value before rendering to the view.



48
49
50
51
52
53
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 48

def exec_server_render_js(js_code, render_options)
  # The secret sauce is passing self as the 3rd param, the js_evaluator
  render_options.set_option(:throw_js_errors, ReactOnRailsPro.configuration.throw_js_errors)
  ReactOnRails::ServerRenderingPool::RubyEmbeddedJavaScript
    .exec_server_render_js(js_code, render_options, self)
end

.prepare_incremental_render_path(js_code, render_options) ⇒ Object



120
121
122
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 120

def prepare_incremental_render_path(js_code, render_options)
  build_render_path(js_code, render_options, "incremental-render")
end

.prepare_render_path(js_code, render_options) ⇒ Object



113
114
115
116
117
118
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 113

def prepare_render_path(js_code, render_options)
  # TODO: Remove the request_digest. See https://github.com/shakacode/react_on_rails_pro/issues/119
  # From the request path
  # path = "/bundles/#{@bundle_hash}/render"
  build_render_path(js_code, render_options, "render")
end

.renderer_bundle_file_nameObject



32
33
34
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 32

def renderer_bundle_file_name
  "#{ReactOnRailsPro::Utils.bundle_hash}.js"
end

.reset_poolObject



12
13
14
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 12

def reset_pool
  ReactOnRailsPro::Request.reset_connection
end

.reset_pool_if_server_bundle_was_modifiedObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 16

def reset_pool_if_server_bundle_was_modified
  # Resetting the pool for server bundle modifications is accomplished by changing the mtime
  # of the server bundle in the request to the remote rendering server.
  # In non-development mode, we don't need to re-read this value.
  if @server_bundle_hash.blank? || ReactOnRails.configuration.development_mode
    @server_bundle_hash = ReactOnRailsPro::Utils.bundle_hash
  end

  unless ReactOnRailsPro.configuration.enable_rsc_support &&
         (@rsc_bundle_hash.blank? || ReactOnRails.configuration.development_mode)
    return
  end

  @rsc_bundle_hash = ReactOnRailsPro::Utils.rsc_bundle_hash
end

.rsc_bundle_hashObject



109
110
111
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 109

def rsc_bundle_hash
  @rsc_bundle_hash ||= ReactOnRailsPro::Utils.rsc_bundle_hash
end

.rsc_renderer_bundle_file_nameObject



36
37
38
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 36

def rsc_renderer_bundle_file_name
  "#{ReactOnRailsPro::Utils.rsc_bundle_hash}.js"
end

.server_bundle_hashObject



105
106
107
# File 'lib/react_on_rails_pro/server_rendering_pool/node_rendering_pool.rb', line 105

def server_bundle_hash
  @server_bundle_hash ||= ReactOnRailsPro::Utils.bundle_hash
end