react_on_rails 16.2.0.beta.3 → 16.2.0.beta.8

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -5
  3. data/CLAUDE.md +59 -0
  4. data/CONTRIBUTING.md +49 -1
  5. data/Gemfile.development_dependencies +1 -1
  6. data/Gemfile.lock +25 -10
  7. data/SWITCHING_CI_CONFIGS.md +55 -6
  8. data/Steepfile +51 -0
  9. data/bin/ci-rerun-failures +68 -22
  10. data/bin/ci-run-failed-specs +26 -2
  11. data/bin/ci-switch-config +262 -34
  12. data/bin/lefthook/check-trailing-newlines +2 -12
  13. data/bin/lefthook/eslint-lint +0 -10
  14. data/bin/lefthook/prettier-format +0 -10
  15. data/bin/lefthook/ruby-autofix +3 -6
  16. data/knip.ts +35 -9
  17. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt +32 -52
  18. data/lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml +5 -1
  19. data/lib/react_on_rails/configuration.rb +56 -12
  20. data/lib/react_on_rails/controller.rb +3 -3
  21. data/lib/react_on_rails/dev/server_manager.rb +11 -4
  22. data/lib/react_on_rails/doctor.rb +249 -2
  23. data/lib/react_on_rails/helper.rb +12 -3
  24. data/lib/react_on_rails/pro_helper.rb +2 -44
  25. data/lib/react_on_rails/react_component/render_options.rb +7 -7
  26. data/lib/react_on_rails/utils.rb +40 -0
  27. data/lib/react_on_rails/version.rb +1 -1
  28. data/react_on_rails_pro/CHANGELOG.md +142 -29
  29. data/react_on_rails_pro/CONTRIBUTING.md +2 -13
  30. data/react_on_rails_pro/Gemfile.development_dependencies +1 -0
  31. data/react_on_rails_pro/Gemfile.lock +24 -3
  32. data/react_on_rails_pro/README.md +559 -38
  33. data/react_on_rails_pro/docs/code-splitting-loadable-components.md +1 -1
  34. data/react_on_rails_pro/docs/contributors-info/releasing.md +2 -2
  35. data/react_on_rails_pro/docs/installation.md +129 -109
  36. data/react_on_rails_pro/docs/node-renderer/basics.md +29 -22
  37. data/react_on_rails_pro/docs/node-renderer/error-reporting-and-tracing.md +8 -8
  38. data/react_on_rails_pro/docs/node-renderer/js-configuration.md +25 -23
  39. data/react_on_rails_pro/docs/node-renderer/troubleshooting.md +2 -0
  40. data/react_on_rails_pro/docs/updating.md +209 -15
  41. data/react_on_rails_pro/lib/react_on_rails_pro/concerns/stream.rb +58 -4
  42. data/react_on_rails_pro/lib/react_on_rails_pro/configuration.rb +17 -3
  43. data/react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb +9 -9
  44. data/react_on_rails_pro/lib/react_on_rails_pro/request.rb +41 -25
  45. data/react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb +27 -7
  46. data/react_on_rails_pro/lib/react_on_rails_pro/utils.rb +3 -3
  47. data/react_on_rails_pro/lib/react_on_rails_pro/version.rb +1 -1
  48. data/react_on_rails_pro/package-scripts.yml +1 -1
  49. data/react_on_rails_pro/package.json +5 -8
  50. data/react_on_rails_pro/packages/node-renderer/src/integrations/api.ts +1 -1
  51. data/react_on_rails_pro/packages/node-renderer/src/master/restartWorkers.ts +39 -17
  52. data/react_on_rails_pro/packages/node-renderer/src/master.ts +15 -4
  53. data/react_on_rails_pro/packages/node-renderer/src/shared/configBuilder.ts +44 -5
  54. data/react_on_rails_pro/packages/node-renderer/src/shared/utils.ts +4 -2
  55. data/react_on_rails_pro/packages/node-renderer/src/worker/handleGracefulShutdown.ts +49 -0
  56. data/react_on_rails_pro/packages/node-renderer/src/worker/vm.ts +3 -3
  57. data/react_on_rails_pro/packages/node-renderer/src/worker.ts +5 -2
  58. data/react_on_rails_pro/packages/node-renderer/tests/helper.ts +8 -8
  59. data/react_on_rails_pro/packages/node-renderer/tests/testingNodeRendererConfigs.js +1 -1
  60. data/react_on_rails_pro/packages/node-renderer/tests/worker.test.ts +19 -19
  61. data/react_on_rails_pro/rakelib/public_key_management.rake +6 -5
  62. data/react_on_rails_pro/rakelib/rbs.rake +47 -0
  63. data/react_on_rails_pro/react_on_rails_pro.gemspec +1 -0
  64. data/react_on_rails_pro/sig/react_on_rails_pro/cache.rbs +13 -0
  65. data/react_on_rails_pro/sig/react_on_rails_pro/configuration.rbs +100 -0
  66. data/react_on_rails_pro/sig/react_on_rails_pro/error.rbs +4 -0
  67. data/react_on_rails_pro/sig/react_on_rails_pro/utils.rbs +7 -0
  68. data/react_on_rails_pro/sig/react_on_rails_pro.rbs +5 -0
  69. data/react_on_rails_pro/spec/dummy/Gemfile.lock +23 -3
  70. data/react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb +3 -3
  71. data/react_on_rails_pro/spec/dummy/bin/dev +4 -8
  72. data/react_on_rails_pro/spec/dummy/client/node-renderer.js +4 -4
  73. data/react_on_rails_pro/spec/dummy/config/environments/production.rb +1 -1
  74. data/react_on_rails_pro/spec/dummy/config/initializers/react_on_rails.rb +28 -12
  75. data/react_on_rails_pro/spec/dummy/config.ru +1 -1
  76. data/react_on_rails_pro/spec/dummy/package.json +2 -2
  77. data/react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb +40 -11
  78. data/react_on_rails_pro/spec/dummy/spec/rails_helper.rb +1 -1
  79. data/react_on_rails_pro/spec/dummy/spec/requests/renderer_console_logging_spec.rb +5 -5
  80. data/react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb +15 -10
  81. data/react_on_rails_pro/spec/dummy/spec/system/renderer_integration_spec.rb +3 -3
  82. data/react_on_rails_pro/spec/dummy/yarn.lock +4 -4
  83. data/react_on_rails_pro/spec/execjs-compatible-dummy/config/environments/production.rb +1 -1
  84. data/react_on_rails_pro/spec/execjs-compatible-dummy/config/initializers/react_on_rails.rb +16 -43
  85. data/react_on_rails_pro/spec/react_on_rails_pro/assets_precompile_spec.rb +15 -18
  86. data/react_on_rails_pro/spec/react_on_rails_pro/cache_spec.rb +1 -1
  87. data/react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb +5 -3
  88. data/react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb +27 -12
  89. data/react_on_rails_pro/spec/react_on_rails_pro/request_spec.rb +0 -27
  90. data/react_on_rails_pro/spec/react_on_rails_pro/spec_helper.rb +1 -1
  91. data/react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb +89 -0
  92. data/react_on_rails_pro/spec/react_on_rails_pro/stream_spec.rb +144 -0
  93. data/react_on_rails_pro/spec/react_on_rails_pro/support/caching.rb +1 -1
  94. data/react_on_rails_pro/spec/react_on_rails_pro/support/mock_block_helper.rb +4 -2
  95. data/sig/react_on_rails/controller.rbs +1 -1
  96. data/sig/react_on_rails/error.rbs +4 -0
  97. data/sig/react_on_rails/helper.rbs +2 -2
  98. data/sig/react_on_rails/json_parse_error.rbs +10 -0
  99. data/sig/react_on_rails/prerender_error.rbs +21 -0
  100. data/sig/react_on_rails/smart_error.rbs +28 -0
  101. data/sig/react_on_rails.rbs +3 -24
  102. metadata +14 -4
  103. data/lib/react_on_rails/pro_utils.rb +0 -37
  104. data/react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/TestingStreamableComponent.jsx +0 -15
@@ -2,10 +2,6 @@
2
2
 
3
3
  module ReactOnRails
4
4
  module ProHelper
5
- IMMEDIATE_HYDRATION_PRO_WARNING = "[REACT ON RAILS] The 'immediate_hydration' feature requires a " \
6
- "React on Rails Pro license. " \
7
- "Please visit https://shakacode.com/react-on-rails-pro to learn more."
8
-
9
5
  # Generates the complete component specification script tag.
10
6
  # Handles both immediate hydration (Pro feature) and standard cases.
11
7
  def generate_component_script(render_options)
@@ -36,17 +32,12 @@ module ReactOnRails
36
32
  component_specification_tag
37
33
  end
38
34
 
39
- pro_warning_badge = pro_warning_badge_if_needed(render_options.explicitly_disabled_pro_options)
40
- "#{pro_warning_badge}\n#{spec_tag}".html_safe
35
+ spec_tag.html_safe
41
36
  end
42
37
 
43
38
  # Generates the complete store hydration script tag.
44
39
  # Handles both immediate hydration (Pro feature) and standard cases.
45
40
  def generate_store_script(redux_store_data)
46
- pro_options_check_result = ReactOnRails::ProUtils.disable_pro_render_options_if_not_licensed(redux_store_data)
47
- redux_store_data = pro_options_check_result[:raw_options]
48
- explicitly_disabled_pro_options = pro_options_check_result[:explicitly_disabled_pro_options]
49
-
50
41
  store_hydration_data = content_tag(:script,
51
42
  json_safe_and_pretty(redux_store_data[:props]).html_safe,
52
43
  type: "application/json",
@@ -67,40 +58,7 @@ module ReactOnRails
67
58
  store_hydration_data
68
59
  end
69
60
 
70
- pro_warning_badge = pro_warning_badge_if_needed(explicitly_disabled_pro_options)
71
- "#{pro_warning_badge}\n#{store_hydration_scripts}".html_safe
72
- end
73
-
74
- def pro_warning_badge_if_needed(explicitly_disabled_pro_options)
75
- return "" unless explicitly_disabled_pro_options.any?
76
-
77
- disabled_features_message = disabled_pro_features_message(explicitly_disabled_pro_options)
78
- warning_message = "[REACT ON RAILS] #{disabled_features_message}\n" \
79
- "Please visit https://shakacode.com/react-on-rails-pro to learn more."
80
- puts warning_message
81
- Rails.logger.warn warning_message
82
-
83
- tooltip_text = "#{disabled_features_message} Click to learn more."
84
-
85
- <<~HTML.strip
86
- <a href="https://shakacode.com/react-on-rails-pro" target="_blank" rel="noopener noreferrer" title="#{tooltip_text}">
87
- <div style="position: fixed; top: 0; right: 0; width: 180px; height: 180px; overflow: hidden; z-index: 9999; pointer-events: none;">
88
- <div style="position: absolute; top: 50px; right: -40px; transform: rotate(45deg); background-color: rgba(220, 53, 69, 0.85); color: white; padding: 7px 40px; text-align: center; font-weight: bold; font-family: sans-serif; font-size: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.3); pointer-events: auto;">
89
- React On Rails Pro Required
90
- </div>
91
- </div>
92
- </a>
93
- HTML
94
- end
95
-
96
- def disabled_pro_features_message(explicitly_disabled_pro_options)
97
- return "".html_safe unless explicitly_disabled_pro_options.any?
98
-
99
- feature_list = explicitly_disabled_pro_options.join(", ")
100
- feature_word = explicitly_disabled_pro_options.size == 1 ? "feature" : "features"
101
- "The '#{feature_list}' #{feature_word} " \
102
- "#{explicitly_disabled_pro_options.size == 1 ? 'requires' : 'require'} a " \
103
- "React on Rails Pro license. "
61
+ store_hydration_scripts.html_safe
104
62
  end
105
63
  end
106
64
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "react_on_rails/utils"
4
- require "react_on_rails/pro_utils"
5
4
 
6
5
  module ReactOnRails
7
6
  module ReactComponent
@@ -15,13 +14,10 @@ module ReactOnRails
15
14
  # TODO: remove the required for named params
16
15
  def initialize(react_component_name: required("react_component_name"), options: required("options"))
17
16
  @react_component_name = react_component_name.camelize
18
-
19
- result = ReactOnRails::ProUtils.disable_pro_render_options_if_not_licensed(options)
20
- @options = result[:raw_options]
21
- @explicitly_disabled_pro_options = result[:explicitly_disabled_pro_options]
17
+ @options = options
22
18
  end
23
19
 
24
- attr_reader :react_component_name, :explicitly_disabled_pro_options
20
+ attr_reader :react_component_name
25
21
 
26
22
  def throw_js_errors
27
23
  options.fetch(:throw_js_errors, false)
@@ -100,7 +96,11 @@ module ReactOnRails
100
96
  end
101
97
 
102
98
  def immediate_hydration
103
- retrieve_configuration_value_for(:immediate_hydration)
99
+ ReactOnRails::Utils.normalize_immediate_hydration(
100
+ options[:immediate_hydration],
101
+ react_component_name,
102
+ "Component"
103
+ )
104
104
  end
105
105
 
106
106
  def to_s
@@ -14,6 +14,46 @@ module ReactOnRails
14
14
  Rainbow('To see the full output, set FULL_TEXT_ERRORS=true.').red
15
15
  } ...\n".freeze
16
16
 
17
+ def self.immediate_hydration_pro_license_warning(name, type = "Component")
18
+ "[REACT ON RAILS] Warning: immediate_hydration: true requires a React on Rails Pro license.\n" \
19
+ "#{type} '#{name}' will fall back to standard hydration behavior.\n" \
20
+ "Visit https://www.shakacode.com/react-on-rails-pro/ for licensing information."
21
+ end
22
+
23
+ # Normalizes the immediate_hydration option value, enforcing Pro license requirements.
24
+ # Returns the normalized boolean value for immediate_hydration.
25
+ #
26
+ # @param value [Boolean, nil] The immediate_hydration option value
27
+ # @param name [String] The name of the component/store (for warning messages)
28
+ # @param type [String] The type ("Component" or "Store") for warning messages
29
+ # @return [Boolean] The normalized immediate_hydration value
30
+ # @raise [ArgumentError] If value is not a boolean or nil
31
+ #
32
+ # Logic:
33
+ # - Validates that value is true, false, or nil
34
+ # - If value is explicitly true (boolean) and no Pro license: warn and return false
35
+ # - If value is nil: return true for Pro users, false for non-Pro users
36
+ # - Otherwise: return the value as-is (allows explicit false to work)
37
+ def self.normalize_immediate_hydration(value, name, type = "Component")
38
+ # Type validation: only accept boolean or nil
39
+ unless [true, false, nil].include?(value)
40
+ raise ArgumentError,
41
+ "[REACT ON RAILS] immediate_hydration must be true, false, or nil. Got: #{value.inspect} (#{value.class})"
42
+ end
43
+
44
+ # Strict equality check: only trigger warning for explicit boolean true
45
+ if value == true && !react_on_rails_pro?
46
+ Rails.logger.warn immediate_hydration_pro_license_warning(name, type)
47
+ return false
48
+ end
49
+
50
+ # If nil, default based on Pro license status
51
+ return react_on_rails_pro? if value.nil?
52
+
53
+ # Return explicit value (including false)
54
+ value
55
+ end
56
+
17
57
  # https://forum.shakacode.com/t/yak-of-the-week-ruby-2-4-pathname-empty-changed-to-look-at-file-size/901
18
58
  # return object if truthy, else return nil
19
59
  def self.truthy_presence(obj)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRails
4
- VERSION = "16.2.0.beta.3"
4
+ VERSION = "16.2.0.beta.8"
5
5
  end