Skip to content

Commit eebed29

Browse files
Move Pro features from core gem to Pro gem
This PR moves all Pro-specific features from lib/react_on_rails/pro/ to the react_on_rails_pro gem, ensuring complete separation between MIT and Pro licensed code. Key Changes: - Move immediate_hydration config from core to Pro gem (default: true in Pro) - Refactor helper methods to use data enhancement pattern - Core gem collects script data, Pro gem enhances it if loaded - Delete lib/react_on_rails/pro/ directory entirely - Update RenderOptions to retrieve immediate_hydration from Pro config - Add comprehensive tests for immediate_hydration option - Update LICENSE.md to reflect that lib/react_on_rails/ is now 100% MIT - Update MONOREPO_MERGER_PLAN.md with new Phase 5 Benefits: - Clean separation: Core gem is 100% MIT licensed - No HTML parsing needed for Pro enhancements - Better architecture: Core gem doesn't know about Pro internals - Backward compatible: Functionality unchanged Technical Implementation: - Core gem's generate_component_script() and generate_store_script() collect script attributes as data structures before HTML generation - If Pro gem is loaded, ReactOnRailsPro::Helper.enhance_*_script_data() adds immediate hydration attributes and scripts - Core gem then generates final HTML from the enhanced data - RenderOptions.immediate_hydration uses retrieve_react_on_rails_pro_config_value_for() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 7bce94a commit eebed29

File tree

13 files changed

+307
-235
lines changed

13 files changed

+307
-235
lines changed

LICENSE.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@ This repository contains code under two different licenses:
1111

1212
The following directories and all their contents are licensed under the **MIT License** (see full text below):
1313

14-
- `lib/react_on_rails/` (excluding `lib/react_on_rails/pro/`)
14+
- `lib/react_on_rails/` (entire directory)
1515
- `packages/react-on-rails/` (entire package)
1616
- All other directories in this repository not explicitly listed as Pro-licensed
1717

1818
### Pro Licensed Code
1919

2020
The following directories and all their contents are licensed under the **React on Rails Pro License**:
2121

22-
- `lib/react_on_rails/pro/`
2322
- `packages/react-on-rails-pro/` (entire package)
2423
- `react_on_rails_pro/` (entire directory)
2524

docs/MONOREPO_MERGER_PLAN.md

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,74 @@ After the initial merge, the following CI adjustments may be needed:
404404

405405
---
406406

407-
#### PR #5: Add Pro Node Renderer Package
407+
#### PR #5: Move Pro Features from Core Gem to Pro Gem
408+
409+
**Branch:** `move-pro-features-to-pro-gem`
410+
411+
**Objectives:**
412+
413+
- Move all Pro features from `lib/react_on_rails/pro/` to Pro gem
414+
- Delete `lib/react_on_rails/pro/` directory entirely
415+
- Ensure core gem is 100% MIT licensed with zero Pro code
416+
417+
**Tasks:**
418+
419+
- [x] Move `immediate_hydration` config from core gem to Pro gem (default: true in Pro)
420+
- [x] Refactor `RenderOptions` to remove Pro utilities
421+
- [x] Refactor helper methods (`generate_component_script`, `generate_store_script`) to use data enhancement pattern
422+
- [x] Create Pro helper module in Pro gem with enhancement methods
423+
- [x] Delete `lib/react_on_rails/pro/` directory entirely
424+
- [x] Update LICENSE.md to remove `lib/react_on_rails/pro/` reference
425+
- [x] Update tests in both gems
426+
427+
**Implementation Details:**
428+
429+
The `immediate_hydration` feature was the only Pro feature in the core gem. The refactoring uses a data enhancement pattern:
430+
431+
1. Core gem collects script attributes/content as data structures (not HTML)
432+
2. If Pro gem loaded, it modifies the data (adds attributes, adds extra scripts)
433+
3. Core gem generates final HTML from the (possibly enhanced) data
434+
435+
**Benefits:**
436+
437+
- ✅ Clean separation: Core gem = 100% MIT, Pro gem = 100% Pro license
438+
- ✅ No HTML parsing needed
439+
- ✅ No Pro warning badge needed (can't enable Pro features without Pro gem)
440+
- ✅ Better architecture: Core gem doesn't know about Pro internals
441+
442+
**License Compliance:**
443+
444+
- [x] **CRITICAL: Update LICENSE.md:**
445+
446+
```md
447+
## MIT License applies to:
448+
449+
- `lib/react_on_rails/` (entire directory)
450+
- `packages/react-on-rails/` (entire package)
451+
452+
## React on Rails Pro License applies to:
453+
454+
- `packages/react-on-rails-pro/` (entire package)
455+
- `react_on_rails_pro/` (entire directory)
456+
```
457+
458+
- [x] Verify no Pro code remains in core gem directories
459+
460+
**Success Criteria:** ✅ All CI checks pass + `lib/react_on_rails/pro/` deleted + Core gem is 100% MIT licensed
461+
462+
**Estimated Duration:** 2-3 days
463+
464+
**Risk Level:** Medium (requires careful refactoring of helper methods)
465+
466+
**Developer Notes:**
467+
468+
- The core gem now calls `ReactOnRailsPro::Helper.enhance_component_script_data` and `ReactOnRailsPro::Helper.enhance_store_script_data` if Pro gem is loaded
469+
- The `immediate_hydration` method in `RenderOptions` now uses `retrieve_react_on_rails_pro_config_value_for(:immediate_hydration)`
470+
- Tests have been updated to mock Pro gem functionality
471+
472+
---
473+
474+
#### PR #6: Add Pro Node Renderer Package
408475

409476
**Branch:** `add-pro-node-renderer`
410477

@@ -455,7 +522,7 @@ After the initial merge, the following CI adjustments may be needed:
455522

456523
### Phase 6: Final Monorepo Restructuring
457524

458-
#### PR #6: Restructure Ruby Gems to Final Layout
525+
#### PR #7: Restructure Ruby Gems to Final Layout
459526

460527
**Branch:** `restructure-ruby-gems`
461528

@@ -522,7 +589,7 @@ After the initial merge, the following CI adjustments may be needed:
522589

523590
### Phase 7: CI/CD & Tooling Unification
524591

525-
#### PR #7: Unify CI/CD Configuration
592+
#### PR #8: Unify CI/CD Configuration
526593

527594
**Branch:** `unify-cicd`
528595

@@ -588,7 +655,7 @@ After the initial merge, the following CI adjustments may be needed:
588655
589656
### Phase 8: Documentation & Polish
590657
591-
#### PR #8: Update Documentation & Examples
658+
#### PR #9: Update Documentation & Examples
592659
593660
**Branch:** `update-docs-examples`
594661

lib/react_on_rails/configuration.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ def self.configuration
4646
components_subdirectory: nil,
4747
make_generated_server_bundle_the_entrypoint: false,
4848
defer_generated_component_packs: false,
49-
# React on Rails Pro (licensed) feature - enables immediate hydration of React components
50-
immediate_hydration: false,
5149
# Maximum time in milliseconds to wait for client-side component registration after page load.
5250
# If exceeded, an error will be thrown for server-side rendered components not registered on the client.
5351
# Set to 0 to disable the timeout and wait indefinitely for component registration.
@@ -72,7 +70,7 @@ class Configuration
7270
:server_render_method, :random_dom_id, :auto_load_bundle,
7371
:same_bundle_for_client_and_server, :rendering_props_extension,
7472
:make_generated_server_bundle_the_entrypoint,
75-
:generated_component_packs_loading_strategy, :immediate_hydration, :rsc_bundle_js_file,
73+
:generated_component_packs_loading_strategy, :rsc_bundle_js_file,
7674
:react_client_manifest_file, :react_server_client_manifest_file, :component_registry_timeout,
7775
:server_bundle_output_path, :enforce_private_server_bundles
7876

@@ -89,7 +87,7 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender
8987
same_bundle_for_client_and_server: nil,
9088
i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil, i18n_yml_safe_load_options: nil,
9189
random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil,
92-
components_subdirectory: nil, auto_load_bundle: nil, immediate_hydration: nil,
90+
components_subdirectory: nil, auto_load_bundle: nil,
9391
rsc_bundle_js_file: nil, react_client_manifest_file: nil, react_server_client_manifest_file: nil,
9492
component_registry_timeout: nil, server_bundle_output_path: nil, enforce_private_server_bundles: nil)
9593
self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
@@ -134,7 +132,6 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender
134132
self.auto_load_bundle = auto_load_bundle
135133
self.make_generated_server_bundle_the_entrypoint = make_generated_server_bundle_the_entrypoint
136134
self.defer_generated_component_packs = defer_generated_component_packs
137-
self.immediate_hydration = immediate_hydration
138135
self.generated_component_packs_loading_strategy = generated_component_packs_loading_strategy
139136
self.server_bundle_output_path = server_bundle_output_path
140137
self.enforce_private_server_bundles = enforce_private_server_bundles

lib/react_on_rails/helper.rb

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@
1111
require "react_on_rails/utils"
1212
require "react_on_rails/json_output"
1313
require "active_support/concern"
14-
require "react_on_rails/pro/helper"
1514

1615
module ReactOnRails
1716
module Helper
1817
include ReactOnRails::Utils::Required
19-
include ReactOnRails::Pro::Helper
2018

2119
COMPONENT_HTML_KEY = "componentHtml"
2220

@@ -793,6 +791,66 @@ def in_mailer?
793791
instrument_method :react_component_hash, type: "ReactOnRails", name: "react_component_hash"
794792
end
795793

794+
# Generates the complete component specification script tag.
795+
# Handles both immediate hydration (Pro feature) and standard cases.
796+
def generate_component_script(render_options)
797+
# Collect script data
798+
script_attrs = {
799+
type: "application/json",
800+
class: "js-react-on-rails-component",
801+
id: "js-react-on-rails-component-#{render_options.dom_id}",
802+
"data-component-name" => render_options.react_component_name,
803+
"data-trace" => (render_options.trace ? true : nil),
804+
"data-dom-id" => render_options.dom_id,
805+
"data-store-dependencies" => render_options.store_dependencies&.to_json
806+
}
807+
808+
script_content = json_safe_and_pretty(render_options.client_props).html_safe
809+
additional_scripts = []
810+
811+
# Let Pro gem enhance if available
812+
if ReactOnRails::Utils.react_on_rails_pro?
813+
result = ReactOnRailsPro::Helper.enhance_component_script_data(
814+
script_attrs: script_attrs,
815+
script_content: script_content,
816+
render_options: render_options
817+
)
818+
script_attrs = result[:script_attrs]
819+
additional_scripts = result[:additional_scripts]
820+
end
821+
822+
# Generate final HTML
823+
main_script = content_tag(:script, script_content, script_attrs)
824+
([main_script] + additional_scripts).join("\n").html_safe
825+
end
826+
827+
# Generates the complete store hydration script tag.
828+
# Handles both immediate hydration (Pro feature) and standard cases.
829+
def generate_store_script(redux_store_data)
830+
script_attrs = {
831+
type: "application/json",
832+
"data-js-react-on-rails-store" => redux_store_data[:store_name].html_safe
833+
}
834+
835+
script_content = json_safe_and_pretty(redux_store_data[:props]).html_safe
836+
additional_scripts = []
837+
838+
# Let Pro gem enhance if available
839+
if ReactOnRails::Utils.react_on_rails_pro?
840+
result = ReactOnRailsPro::Helper.enhance_store_script_data(
841+
script_attrs: script_attrs,
842+
script_content: script_content,
843+
redux_store_data: redux_store_data
844+
)
845+
script_attrs = result[:script_attrs]
846+
additional_scripts = result[:additional_scripts]
847+
end
848+
849+
# Generate final HTML
850+
main_script = content_tag(:script, script_content, script_attrs)
851+
([main_script] + additional_scripts).join("\n").html_safe
852+
end
853+
796854
def raise_missing_autoloaded_bundle(react_component_name)
797855
msg = <<~MSG
798856
**ERROR** ReactOnRails: Component "#{react_component_name}" is configured as "auto_load_bundle: true"

lib/react_on_rails/pro/NOTICE

Lines changed: 0 additions & 21 deletions
This file was deleted.

lib/react_on_rails/pro/helper.rb

Lines changed: 0 additions & 122 deletions
This file was deleted.

0 commit comments

Comments
 (0)