react_on_rails_pro 16.6.0.rc.0 → 16.6.0.rc.1

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: f373b7e8f1b22b6a346f76eee9e85bf438104439a5d6250ccd8be773cbbdf86d
4
- data.tar.gz: a846f06b5f699c0bf61404237593be4d72e105cec55a152a77ecc80de549efd0
3
+ metadata.gz: 3c916f9674e2623f411de371a45f7a4016780b2f0f2b267b2be6adc00b73e256
4
+ data.tar.gz: ea25bb1c946748b59252d44a5e42bdab08b9782d062ac1e03d35480e1d080f2f
5
5
  SHA512:
6
- metadata.gz: b97234a2ae969d0625912780700bffebe01268b7c183b70b56d1707dd6f0ce012f2b7b8d3ab71315d5667bacbb71188c67bad93715a3171cf063b7a0dbc2d340
7
- data.tar.gz: 9433436cd0acf2c2c8a523972946010aa3dc5905d7efc980ce7586bb70bf77b5535deab295f9a5b2fe917c26eca13ce4367dd109184c9df2154c0fab6258c28a
6
+ metadata.gz: 377bbdc3a94e443fa1fda13389603f1593a8fe3457af9ccc66ebfe5b710164cf1b7a225886d44e44edec6a73fd4bb4cd31813ee2c6f57f02c884efb79a1fb14f
7
+ data.tar.gz: c23fcc4de60626c285b8aeb47fb9b334fac21b57950976aa947be27e51831e3ef221a9e482fb3ba4dccaf693bd2aa755ab13f802780b27eca0411ac65dbca83a
data/Gemfile.lock CHANGED
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: ..
11
11
  specs:
12
- react_on_rails (16.6.0.rc.0)
12
+ react_on_rails (16.6.0.rc.1)
13
13
  addressable
14
14
  connection_pool
15
15
  execjs (~> 2.5)
@@ -20,7 +20,7 @@ PATH
20
20
  PATH
21
21
  remote: .
22
22
  specs:
23
- react_on_rails_pro (16.6.0.rc.0)
23
+ react_on_rails_pro (16.6.0.rc.1)
24
24
  addressable
25
25
  async (>= 2.29)
26
26
  connection_pool
@@ -29,7 +29,7 @@ PATH
29
29
  httpx (~> 1.5)
30
30
  jwt (~> 2.7)
31
31
  rainbow
32
- react_on_rails (= 16.6.0.rc.0)
32
+ react_on_rails (= 16.6.0.rc.1)
33
33
 
34
34
  GEM
35
35
  remote: https://rubygems.org/
@@ -128,7 +128,10 @@ module ReactOnRailsProHelper
128
128
  # stream_react_component doesn't have the prerender option
129
129
  # Because setting prerender to false is equivalent to calling react_component with prerender: false
130
130
  options[:prerender] = true
131
- options = options.merge(immediate_hydration: true) unless options.key?(:immediate_hydration)
131
+ if options.key?(:immediate_hydration)
132
+ ReactOnRails::Helper.warn_removed_immediate_hydration_option("stream_react_component")
133
+ options.delete(:immediate_hydration)
134
+ end
132
135
 
133
136
  # Extract streaming-specific callback
134
137
  on_complete = options.delete(:on_complete)
@@ -15,6 +15,7 @@ module ReactOnRailsPro
15
15
  renderer_http_pool_size: Configuration::DEFAULT_RENDERER_HTTP_POOL_SIZE,
16
16
  renderer_http_pool_timeout: Configuration::DEFAULT_RENDERER_HTTP_POOL_TIMEOUT,
17
17
  renderer_http_pool_warn_timeout: Configuration::DEFAULT_RENDERER_HTTP_POOL_WARN_TIMEOUT,
18
+ renderer_http_keep_alive_timeout: Configuration::DEFAULT_RENDERER_HTTP_KEEP_ALIVE_TIMEOUT,
18
19
  renderer_password: nil,
19
20
  tracing: Configuration::DEFAULT_TRACING,
20
21
  dependency_globs: Configuration::DEFAULT_DEPENDENCY_GLOBS,
@@ -44,6 +45,7 @@ module ReactOnRailsPro
44
45
  DEFAULT_RENDERER_HTTP_POOL_SIZE = 10
45
46
  DEFAULT_RENDERER_HTTP_POOL_TIMEOUT = 5
46
47
  DEFAULT_RENDERER_HTTP_POOL_WARN_TIMEOUT = 0.25
48
+ DEFAULT_RENDERER_HTTP_KEEP_ALIVE_TIMEOUT = 30
47
49
  DEFAULT_SSR_TIMEOUT = 5
48
50
  DEFAULT_PRERENDER_CACHING = false
49
51
  DEFAULT_TRACING = false
@@ -72,7 +74,7 @@ module ReactOnRailsPro
72
74
  :rsc_payload_generation_url_path, :rsc_bundle_js_file, :react_client_manifest_file,
73
75
  :react_server_client_manifest_file
74
76
 
75
- attr_reader :concurrent_component_streaming_buffer_size
77
+ attr_reader :concurrent_component_streaming_buffer_size, :renderer_http_keep_alive_timeout
76
78
 
77
79
  # Sets the buffer size for concurrent component streaming.
78
80
  #
@@ -91,10 +93,23 @@ module ReactOnRailsPro
91
93
  @concurrent_component_streaming_buffer_size = value
92
94
  end
93
95
 
96
+ # Sets the keep-alive timeout (in seconds) for persistent HTTP connections to the node renderer.
97
+ #
98
+ # @param value [Numeric, nil] A positive number or nil (to use the HTTPX default)
99
+ # @raise [ReactOnRailsPro::Error] if value is not a positive number or nil
100
+ def renderer_http_keep_alive_timeout=(value)
101
+ unless value.nil? || (value.is_a?(Numeric) && value.positive? && value.finite?)
102
+ raise ReactOnRailsPro::Error,
103
+ "config.renderer_http_keep_alive_timeout must be a finite positive number or nil"
104
+ end
105
+ @renderer_http_keep_alive_timeout = value
106
+ end
107
+
94
108
  def initialize(renderer_url: nil, renderer_password: nil, server_renderer: nil, # rubocop:disable Metrics/AbcSize
95
109
  renderer_use_fallback_exec_js: nil, prerender_caching: nil,
96
110
  renderer_http_pool_size: nil, renderer_http_pool_timeout: nil,
97
- renderer_http_pool_warn_timeout: nil, tracing: nil,
111
+ renderer_http_pool_warn_timeout: nil, renderer_http_keep_alive_timeout: nil,
112
+ tracing: nil,
98
113
  dependency_globs: nil, excluded_dependency_globs: nil, rendering_returns_promises: nil,
99
114
  remote_bundle_cache_adapter: nil, ssr_pre_hook_js: nil, assets_to_copy: nil,
100
115
  renderer_request_retry_limit: nil, throw_js_errors: nil, ssr_timeout: nil,
@@ -111,6 +126,7 @@ module ReactOnRailsPro
111
126
  self.renderer_http_pool_size = renderer_http_pool_size
112
127
  self.renderer_http_pool_timeout = renderer_http_pool_timeout
113
128
  self.renderer_http_pool_warn_timeout = renderer_http_pool_warn_timeout
129
+ self.renderer_http_keep_alive_timeout = renderer_http_keep_alive_timeout
114
130
  self.tracing = tracing
115
131
  self.rendering_returns_promises = server_renderer == "NodeRenderer" ? rendering_returns_promises : false
116
132
  self.dependency_globs = dependency_globs
@@ -230,12 +246,16 @@ module ReactOnRailsPro
230
246
 
231
247
  def setup_renderer_password
232
248
  # Explicit passwords, including values loaded from ENV in the initializer, skip URL extraction.
233
- # Blank values fall through so URL extraction and production validation still catch misconfiguration.
249
+ # Blank values (nil or "") fall through so URL extraction and ENV fallback still apply.
234
250
  return if renderer_password.present?
235
251
 
236
252
  uri = URI(renderer_url)
237
253
  self.renderer_password = uri.password
238
254
 
255
+ # Mirror Node-side defaults: if Rails config and URL are both missing a password,
256
+ # use RENDERER_PASSWORD from env.
257
+ self.renderer_password = ENV.fetch("RENDERER_PASSWORD", nil) if renderer_password.blank?
258
+
239
259
  validate_renderer_password_for_production
240
260
  end
241
261
 
@@ -260,17 +280,23 @@ module ReactOnRailsPro
260
280
  is required. In all other environments, you must explicitly configure a password to secure
261
281
  communication between Rails and the Node Renderer.
262
282
 
263
- To fix this, set the RENDERER_PASSWORD environment variable and configure it in your initializer:
283
+ To fix this, set the RENDERER_PASSWORD environment variable:
284
+
285
+ export RENDERER_PASSWORD="your-secure-password"
286
+
287
+ Rails reads it automatically. If you prefer to make it explicit in your initializer:
264
288
 
265
289
  # config/initializers/react_on_rails_pro.rb
266
290
  ReactOnRailsPro.configure do |config|
267
291
  config.renderer_password = ENV.fetch("RENDERER_PASSWORD")
268
292
  end
269
293
 
270
- Then set the same password for the Node Renderer via the RENDERER_PASSWORD environment variable.
271
- Note: setting ENV["RENDERER_PASSWORD"] alone is not enough on the Ruby side unless
272
- config.renderer_password is explicitly assigned from ENV.
273
- An empty-string assignment still counts as missing and will raise in production-like environments.
294
+ Set the same password for the Node Renderer via the RENDERER_PASSWORD environment variable.
295
+ Rails resolves the password in this order:
296
+ 1) config.renderer_password (blank values fall through to the next step)
297
+ 2) Password embedded in config.renderer_url (for example, https://:password@host:3800)
298
+ 3) ENV["RENDERER_PASSWORD"]
299
+
274
300
  If Rails and the Node Renderer disagree about startup behavior, verify both RAILS_ENV and NODE_ENV.
275
301
 
276
302
  Environment matrix:
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRailsPro
4
+ # Status code 400 indicates the renderer rejected the request payload or encountered an unhandled render error.
5
+ STATUS_BAD_REQUEST = 400
4
6
  # Status code 410 means to resend the request with the updated bundle.
5
7
  STATUS_SEND_BUNDLE = 410
6
8
  # Status code 412 means protocol versions are incompatible between the server and the renderer.
@@ -297,11 +297,11 @@ module ReactOnRailsPro
297
297
  # :write_timeout
298
298
  # :request_timeout
299
299
  # :operation_timeout
300
- # :keep_alive_timeout
301
300
  timeout: {
302
301
  connect_timeout: ReactOnRailsPro.configuration.renderer_http_pool_timeout,
303
- read_timeout: ReactOnRailsPro.configuration.ssr_timeout
304
- }
302
+ read_timeout: ReactOnRailsPro.configuration.ssr_timeout,
303
+ keep_alive_timeout: ReactOnRailsPro.configuration.renderer_http_keep_alive_timeout
304
+ }.compact
305
305
  )
306
306
  rescue StandardError => e
307
307
  message = <<~MSG
@@ -309,6 +309,7 @@ module ReactOnRailsPro
309
309
  renderer_http_pool_size = #{ReactOnRailsPro.configuration.renderer_http_pool_size}
310
310
  renderer_http_pool_timeout = #{ReactOnRailsPro.configuration.renderer_http_pool_timeout}
311
311
  renderer_http_pool_warn_timeout = #{ReactOnRailsPro.configuration.renderer_http_pool_warn_timeout}
312
+ renderer_http_keep_alive_timeout = #{ReactOnRailsPro.configuration.renderer_http_keep_alive_timeout}
312
313
  renderer_url = #{url}
313
314
  Be sure to use a url that contains the protocol of http or https.
314
315
  Original error is
@@ -74,9 +74,10 @@ module ReactOnRailsPro
74
74
  ReactOnRailsPro::Error.raise_duplicate_bundle_upload_error if send_bundle
75
75
 
76
76
  eval_js(js_code, render_options, send_bundle: true)
77
- when 400
77
+ when ReactOnRailsPro::STATUS_BAD_REQUEST
78
78
  raise ReactOnRailsPro::Error,
79
- "Renderer unhandled error at the VM level: #{response.status}:\n#{response.body}"
79
+ "Renderer rejected malformed request or hit an unhandled VM error: " \
80
+ "#{response.status}:\n#{response.body}"
80
81
  else
81
82
  raise ReactOnRailsPro::Error,
82
83
  "Unexpected response code from renderer: #{response.status}:\n#{response.body}"
@@ -140,6 +140,10 @@ module ReactOnRailsPro
140
140
  ReactOnRailsPro::Error.raise_duplicate_bundle_upload_error if send_bundle
141
141
 
142
142
  true
143
+ when ReactOnRailsPro::STATUS_BAD_REQUEST
144
+ raise ReactOnRailsPro::Error,
145
+ "Renderer rejected malformed request or hit an unhandled VM error: " \
146
+ "#{response.status}:\n#{error_body}"
143
147
  when ReactOnRailsPro::STATUS_INCOMPATIBLE
144
148
  raise ReactOnRailsPro::Error, error_body
145
149
  else
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRailsPro
4
- VERSION = "16.6.0.rc.0"
4
+ VERSION = "16.6.0.rc.1"
5
5
  PROTOCOL_VERSION = "2.0.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react_on_rails_pro
3
3
  version: !ruby/object:Gem::Version
4
- version: 16.6.0.rc.0
4
+ version: 16.6.0.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-02 00:00:00.000000000 Z
11
+ date: 2026-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 16.6.0.rc.0
131
+ version: 16.6.0.rc.1
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 16.6.0.rc.0
138
+ version: 16.6.0.rc.1
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: bundler
141
141
  requirement: !ruby/object:Gem::Requirement