Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions lib/react_on_rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ def self.configuration
components_subdirectory: nil,
make_generated_server_bundle_the_entrypoint: false,
defer_generated_component_packs: false,
# React on Rails Pro (licensed) feature - enables immediate hydration of React components
immediate_hydration: false,
# Maximum time in milliseconds to wait for client-side component registration after page load.
# If exceeded, an error will be thrown for server-side rendered components not registered on the client.
# Set to 0 to disable the timeout and wait indefinitely for component registration.
Expand All @@ -64,7 +62,7 @@ class Configuration
:server_render_method, :random_dom_id, :auto_load_bundle,
:same_bundle_for_client_and_server, :rendering_props_extension,
:make_generated_server_bundle_the_entrypoint,
:generated_component_packs_loading_strategy, :immediate_hydration,
:generated_component_packs_loading_strategy,
:component_registry_timeout,
:server_bundle_output_path, :enforce_private_server_bundles

Expand All @@ -81,7 +79,7 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender
same_bundle_for_client_and_server: nil,
i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil, i18n_yml_safe_load_options: nil,
random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil,
components_subdirectory: nil, auto_load_bundle: nil, immediate_hydration: nil,
components_subdirectory: nil, auto_load_bundle: nil,
component_registry_timeout: nil, server_bundle_output_path: nil, enforce_private_server_bundles: nil)
self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
self.generated_assets_dirs = generated_assets_dirs
Expand Down Expand Up @@ -122,7 +120,6 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender
self.auto_load_bundle = auto_load_bundle
self.make_generated_server_bundle_the_entrypoint = make_generated_server_bundle_the_entrypoint
self.defer_generated_component_packs = defer_generated_component_packs
self.immediate_hydration = immediate_hydration
self.generated_component_packs_loading_strategy = generated_component_packs_loading_strategy
self.server_bundle_output_path = server_bundle_output_path
self.enforce_private_server_bundles = enforce_private_server_bundles
Expand Down
2 changes: 1 addition & 1 deletion lib/react_on_rails/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module Controller
# Be sure to include view helper `redux_store_hydration_data` at the end of your layout or view
# or else there will be no client side hydration of your stores.
def redux_store(store_name, props: {}, immediate_hydration: nil)
immediate_hydration = ReactOnRails.configuration.immediate_hydration if immediate_hydration.nil?
immediate_hydration = ReactOnRails::ProUtils.immediate_hydration_config if immediate_hydration.nil?
redux_store_data = { store_name: store_name,
props: props,
immediate_hydration: immediate_hydration }
Expand Down
34 changes: 26 additions & 8 deletions lib/react_on_rails/doctor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ def check_shakapacker_configuration_details

def check_react_on_rails_configuration_details
check_react_on_rails_initializer
check_react_on_rails_pro_initializer
check_deprecated_configuration_settings
check_breaking_changes_warnings
end
Expand Down Expand Up @@ -664,6 +665,29 @@ def check_react_on_rails_initializer
end
end

def check_react_on_rails_pro_initializer
config_path = "config/initializers/react_on_rails_pro.rb"

return unless File.exist?(config_path)

begin
content = File.read(config_path)

checker.add_info("\n📋 React on Rails Pro Configuration:")
checker.add_info("📍 Documentation: https://www.shakacode.com/react-on-rails-pro/")

# Immediate hydration (Pro feature)
immediate_hydration_match = content.match(/config\.immediate_hydration\s*=\s*([^\s\n,]+)/)
if immediate_hydration_match
checker.add_info(" immediate_hydration: #{immediate_hydration_match[1]}")
else
checker.add_info(" immediate_hydration: false (default)")
end
rescue StandardError => e
checker.add_warning("⚠️ Unable to read react_on_rails_pro.rb: #{e.message}")
end
end

def analyze_server_rendering_config(content)
checker.add_info("\n🖥️ Server Rendering:")

Expand Down Expand Up @@ -701,7 +725,7 @@ def analyze_server_rendering_config(content)
end
# rubocop:enable Metrics/AbcSize

# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
# rubocop:disable Metrics/CyclomaticComplexity
def analyze_performance_config(content)
checker.add_info("\n⚡ Performance & Loading:")

Expand Down Expand Up @@ -732,19 +756,13 @@ def analyze_performance_config(content)
auto_load_match = content.match(/config\.auto_load_bundle\s*=\s*([^\s\n,]+)/)
checker.add_info(" auto_load_bundle: #{auto_load_match[1]}") if auto_load_match

# Immediate hydration (Pro feature)
immediate_hydration_match = content.match(/config\.immediate_hydration\s*=\s*([^\s\n,]+)/)
if immediate_hydration_match
checker.add_info(" immediate_hydration: #{immediate_hydration_match[1]} (React on Rails Pro)")
end

# Component registry timeout
timeout_match = content.match(/config\.component_registry_timeout\s*=\s*([^\s\n,]+)/)
return unless timeout_match

checker.add_info(" component_registry_timeout: #{timeout_match[1]}ms")
end
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
# rubocop:enable Metrics/CyclomaticComplexity

# rubocop:disable Metrics/AbcSize
def analyze_development_config(content)
Expand Down
2 changes: 1 addition & 1 deletion lib/react_on_rails/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def react_component_hash(component_name, options = {})
# immediate_hydration: false -- React on Rails Pro (licensed) feature. Pass as true if you wish to
# hydrate this store immediately instead of waiting for the page to load.
def redux_store(store_name, props: {}, defer: false, immediate_hydration: nil)
immediate_hydration = ReactOnRails.configuration.immediate_hydration if immediate_hydration.nil?
immediate_hydration = ReactOnRails::ProUtils.immediate_hydration_config if immediate_hydration.nil?

redux_store_data = { store_name: store_name,
props: props,
Expand Down
11 changes: 10 additions & 1 deletion lib/react_on_rails/pro_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ def self.support_pro_features?
ReactOnRails::Utils.react_on_rails_pro?
end

# Returns the immediate_hydration configuration value
# @return [Boolean] immediate_hydration setting from Pro config if Pro is available, false otherwise
def self.immediate_hydration_config
return false unless support_pro_features?

ReactOnRailsPro.configuration.immediate_hydration
end

def self.disable_pro_render_options_if_not_licensed(raw_options)
return raw_options if support_pro_features?

Expand All @@ -18,7 +26,8 @@ def self.disable_pro_render_options_if_not_licensed(raw_options)
PRO_ONLY_OPTIONS.each do |option|
# Determine if this option is enabled (either explicitly or via global config)
option_enabled = if raw_options[option].nil?
ReactOnRails.configuration.send(option)
# Use the Pro config helper to get the global config value
immediate_hydration_config
else
raw_options[option]
end
Expand Down
4 changes: 3 additions & 1 deletion lib/react_on_rails/react_component/render_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ def logging_on_server
end

def immediate_hydration
retrieve_configuration_value_for(:immediate_hydration)
options.fetch(:immediate_hydration) do
ReactOnRails::ProUtils.immediate_hydration_config
end
end

def to_s
Expand Down
10 changes: 7 additions & 3 deletions react_on_rails_pro/lib/react_on_rails_pro/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def self.configuration
rsc_payload_generation_url_path: Configuration::DEFAULT_RSC_PAYLOAD_GENERATION_URL_PATH,
rsc_bundle_js_file: Configuration::DEFAULT_RSC_BUNDLE_JS_FILE,
react_client_manifest_file: Configuration::DEFAULT_REACT_CLIENT_MANIFEST_FILE,
react_server_client_manifest_file: Configuration::DEFAULT_REACT_SERVER_CLIENT_MANIFEST_FILE
react_server_client_manifest_file: Configuration::DEFAULT_REACT_SERVER_CLIENT_MANIFEST_FILE,
immediate_hydration: Configuration::DEFAULT_IMMEDIATE_HYDRATION
)
end

Expand All @@ -59,6 +60,7 @@ class Configuration # rubocop:disable Metrics/ClassLength
DEFAULT_RSC_BUNDLE_JS_FILE = "rsc-bundle.js"
DEFAULT_REACT_CLIENT_MANIFEST_FILE = "react-client-manifest.json"
DEFAULT_REACT_SERVER_CLIENT_MANIFEST_FILE = "react-server-client-manifest.json"
DEFAULT_IMMEDIATE_HYDRATION = false

attr_accessor :renderer_url, :renderer_password, :tracing,
:server_renderer, :renderer_use_fallback_exec_js, :prerender_caching,
Expand All @@ -68,7 +70,7 @@ class Configuration # rubocop:disable Metrics/ClassLength
:renderer_request_retry_limit, :throw_js_errors, :ssr_timeout,
:profile_server_rendering_js_code, :raise_non_shell_server_rendering_errors, :enable_rsc_support,
:rsc_payload_generation_url_path, :rsc_bundle_js_file, :react_client_manifest_file,
:react_server_client_manifest_file
:react_server_client_manifest_file, :immediate_hydration

def initialize(renderer_url: nil, renderer_password: nil, server_renderer: nil, # rubocop:disable Metrics/AbcSize
renderer_use_fallback_exec_js: nil, prerender_caching: nil,
Expand All @@ -79,7 +81,8 @@ def initialize(renderer_url: nil, renderer_password: nil, server_renderer: nil,
renderer_request_retry_limit: nil, throw_js_errors: nil, ssr_timeout: nil,
profile_server_rendering_js_code: nil, raise_non_shell_server_rendering_errors: nil,
enable_rsc_support: nil, rsc_payload_generation_url_path: nil,
rsc_bundle_js_file: nil, react_client_manifest_file: nil, react_server_client_manifest_file: nil)
rsc_bundle_js_file: nil, react_client_manifest_file: nil, react_server_client_manifest_file: nil,
immediate_hydration: nil)
self.renderer_url = renderer_url
self.renderer_password = renderer_password
self.server_renderer = server_renderer
Expand All @@ -105,6 +108,7 @@ def initialize(renderer_url: nil, renderer_password: nil, server_renderer: nil,
self.rsc_bundle_js_file = rsc_bundle_js_file
self.react_client_manifest_file = react_client_manifest_file
self.react_server_client_manifest_file = react_server_client_manifest_file
self.immediate_hydration = immediate_hydration
end

def setup_config_values
Expand Down
1 change: 0 additions & 1 deletion spec/dummy/config/initializers/react_on_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,5 @@ def self.adjust_props_for_client_side_hydration(component_name, props)
config.rendering_props_extension = RenderingPropsExtension
config.components_subdirectory = "startup"
config.auto_load_bundle = true
config.immediate_hydration = false
config.generated_component_packs_loading_strategy = :defer
end
11 changes: 2 additions & 9 deletions spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,8 @@ def self.pro_attribution_comment
stub_const("ReactOnRailsPro", pro_module)
stub_const("ReactOnRailsPro::Utils", utils_module)

# Configure immediate_hydration to true for tests since they expect that behavior
ReactOnRails.configure do |config|
config.immediate_hydration = true
end
end

after do
# Reset to default - avoid validation issues by setting directly
ReactOnRails.configuration.immediate_hydration = false
# Stub immediate_hydration to true for tests since they expect that behavior
allow(ReactOnRails::ProUtils).to receive(:immediate_hydration_config).and_return(true)
end

let(:hash) do
Expand Down
7 changes: 2 additions & 5 deletions spec/dummy/spec/system/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,9 @@ def self.pro_attribution_comment
end
stub_const("ReactOnRailsPro", pro_module)
stub_const("ReactOnRailsPro::Utils", utils_module)
end

around do |example|
ReactOnRails.configure { |config| config.immediate_hydration = true }
example.run
ReactOnRails.configure { |config| config.immediate_hydration = false }
# Stub immediate_hydration to true since these tests expect that behavior
allow(ReactOnRails::ProUtils).to receive(:immediate_hydration_config).and_return(true)
end
end

Expand Down
Loading