Skip to content

Commit ec29344

Browse files
justin808claude
andcommitted
Add RBS type signatures for React on Rails gem
This commit adds comprehensive RBS (Ruby Signature) type definitions for the React on Rails gem to improve type safety and IDE support. Changes: - Add RBS gem to development dependencies - Create sig/ directory with type signatures for core modules: - ReactOnRails module and main classes - Configuration class with all attributes and methods - Helper module with view helper methods - ServerRenderingPool module - Utils, PackerUtils, TestHelper modules - Controller, GitUtils, VersionChecker modules - Add rake tasks for RBS validation (rbs:validate, rbs:check, rbs:list) - Include README documentation for RBS usage Benefits: - Better IDE autocomplete and IntelliSense support - Static type checking with tools like Steep - Improved API documentation - Early detection of type-related bugs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 2acff83 commit ec29344

14 files changed

+365
-0
lines changed

Gemfile.development_dependencies

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ group :development, :test do
3333
gem "pry-doc"
3434
gem "pry-rails"
3535
gem "pry-rescue"
36+
gem "rbs", require: false
3637
gem "rubocop", "1.61.0", require: false
3738
gem "rubocop-performance", "~>1.20.0", require: false
3839
gem "rubocop-rspec", "~>2.26", require: false

Gemfile.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ GEM
267267
rb-fsevent (0.11.2)
268268
rb-inotify (0.10.1)
269269
ffi (~> 1.0)
270+
rbs (3.9.5)
271+
logger
270272
rdoc (6.15.1)
271273
erb
272274
psych (>= 4.0.0)
@@ -437,6 +439,7 @@ DEPENDENCIES
437439
pry-rescue
438440
puma (~> 6.0)
439441
rails (~> 7.1)
442+
rbs
440443
react_on_rails!
441444
rspec-rails
442445
rspec-retry

rakelib/rbs.rake

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
namespace :rbs do
4+
desc "Validate RBS type signatures"
5+
task :validate do
6+
require "rbs"
7+
require "rbs/cli"
8+
9+
puts "Validating RBS type signatures..."
10+
11+
# Run RBS validate
12+
result = system("bundle exec rbs -I sig validate")
13+
14+
if result
15+
puts "✓ RBS validation passed"
16+
else
17+
puts "✗ RBS validation failed"
18+
exit 1
19+
end
20+
end
21+
22+
desc "Check RBS type signatures (alias for validate)"
23+
task check: :validate
24+
25+
desc "List all RBS files"
26+
task :list do
27+
sig_files = Dir.glob("sig/**/*.rbs")
28+
puts "RBS type signature files:"
29+
sig_files.each { |f| puts " #{f}" }
30+
puts "\nTotal: #{sig_files.count} files"
31+
end
32+
end

sig/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# RBS Type Signatures
2+
3+
This directory contains RBS (Ruby Signature) type definitions for the React on Rails gem.
4+
5+
## What is RBS?
6+
7+
RBS is Ruby's official type signature language. It provides type information for Ruby code, enabling:
8+
9+
- Better IDE support and autocomplete
10+
- Static type checking with tools like Steep
11+
- Improved documentation
12+
- Early detection of type-related bugs
13+
14+
## Structure
15+
16+
The signatures are organized to mirror the `lib/` directory structure:
17+
18+
- `react_on_rails.rbs` - Main module and core classes
19+
- `react_on_rails/configuration.rbs` - Configuration class types
20+
- `react_on_rails/helper.rbs` - View helper method signatures
21+
- `react_on_rails/server_rendering_pool.rbs` - Server rendering types
22+
- `react_on_rails/utils.rbs` - Utility method signatures
23+
- And more...
24+
25+
## Validation
26+
27+
To validate the RBS signatures:
28+
29+
```bash
30+
bundle exec rake rbs:validate
31+
```
32+
33+
Or directly:
34+
35+
```bash
36+
bundle exec rbs -I sig validate
37+
```
38+
39+
To list all RBS files:
40+
41+
```bash
42+
bundle exec rake rbs:list
43+
```
44+
45+
## Development
46+
47+
When adding new public methods or classes to the gem, please also add corresponding RBS signatures.
48+
49+
For more information about RBS:
50+
51+
- [RBS Documentation](https://github.com/ruby/rbs)
52+
- [RBS Syntax Guide](https://github.com/ruby/rbs/blob/master/docs/syntax.md)

sig/react_on_rails.rbs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Type signatures for ReactOnRails gem
2+
3+
module ReactOnRails
4+
VERSION: String
5+
6+
DEFAULT_GENERATED_ASSETS_DIR: String
7+
DEFAULT_COMPONENT_REGISTRY_TIMEOUT: Integer
8+
9+
def self.configure: () { (Configuration) -> void } -> void
10+
def self.configuration: () -> Configuration
11+
12+
class Error < StandardError
13+
end
14+
15+
class PrerenderError < Error
16+
attr_accessor js_code: String?
17+
attr_accessor err: Hash[Symbol, untyped]
18+
attr_accessor js_message: String
19+
20+
def initialize: (
21+
?component_name: String?,
22+
?js_code: String?,
23+
?err: Hash[Symbol, untyped],
24+
?props: (Hash[Symbol, untyped] | String)?,
25+
?js_message: String
26+
) -> void
27+
28+
def console_messages: () -> Array[String]
29+
def base_message: () -> String
30+
def build_message: () -> String
31+
end
32+
33+
class JsonParseError < Error
34+
def initialize: (Hash[Symbol, untyped] err) -> void
35+
end
36+
end
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
module ReactOnRails
2+
class Configuration
3+
attr_accessor node_modules_location: String?
4+
attr_accessor server_bundle_js_file: String
5+
attr_accessor prerender: bool
6+
attr_accessor replay_console: bool
7+
attr_accessor trace: bool
8+
attr_accessor development_mode: bool
9+
attr_accessor logging_on_server: bool
10+
attr_accessor server_renderer_pool_size: Integer
11+
attr_accessor server_renderer_timeout: Integer
12+
attr_accessor skip_display_none: bool?
13+
attr_accessor raise_on_prerender_error: bool
14+
attr_accessor generated_assets_dirs: Array[String]?
15+
attr_accessor generated_assets_dir: String
16+
attr_accessor components_subdirectory: String?
17+
attr_accessor webpack_generated_files: Array[String]
18+
attr_accessor rendering_extension: String?
19+
attr_accessor build_test_command: String
20+
attr_accessor build_production_command: String
21+
attr_accessor i18n_dir: String?
22+
attr_accessor i18n_yml_dir: String?
23+
attr_accessor i18n_output_format: Symbol?
24+
attr_accessor i18n_yml_safe_load_options: Hash[Symbol, untyped]?
25+
attr_accessor defer_generated_component_packs: bool
26+
attr_accessor server_render_method: String?
27+
attr_accessor random_dom_id: bool
28+
attr_accessor auto_load_bundle: bool
29+
attr_accessor same_bundle_for_client_and_server: bool
30+
attr_accessor rendering_props_extension: String?
31+
attr_accessor make_generated_server_bundle_the_entrypoint: bool
32+
attr_accessor generated_component_packs_loading_strategy: Symbol?
33+
attr_accessor immediate_hydration: bool
34+
attr_accessor component_registry_timeout: Integer
35+
attr_accessor server_bundle_output_path: String?
36+
attr_accessor enforce_private_server_bundles: bool
37+
38+
def initialize: (
39+
?node_modules_location: String?,
40+
?server_bundle_js_file: String?,
41+
?prerender: bool?,
42+
?replay_console: bool?,
43+
?make_generated_server_bundle_the_entrypoint: bool?,
44+
?trace: bool?,
45+
?development_mode: bool?,
46+
?defer_generated_component_packs: bool?,
47+
?logging_on_server: bool?,
48+
?server_renderer_pool_size: Integer?,
49+
?server_renderer_timeout: Integer?,
50+
?raise_on_prerender_error: bool,
51+
?skip_display_none: bool?,
52+
?generated_assets_dirs: Array[String]?,
53+
?generated_assets_dir: String?,
54+
?webpack_generated_files: Array[String]?,
55+
?rendering_extension: String?,
56+
?build_test_command: String?,
57+
?build_production_command: String?,
58+
?generated_component_packs_loading_strategy: Symbol?,
59+
?same_bundle_for_client_and_server: bool?,
60+
?i18n_dir: String?,
61+
?i18n_yml_dir: String?,
62+
?i18n_output_format: Symbol?,
63+
?i18n_yml_safe_load_options: Hash[Symbol, untyped]?,
64+
?random_dom_id: bool?,
65+
?server_render_method: String?,
66+
?rendering_props_extension: String?,
67+
?components_subdirectory: String?,
68+
?auto_load_bundle: bool?,
69+
?immediate_hydration: bool?,
70+
?component_registry_timeout: Integer?,
71+
?server_bundle_output_path: String?,
72+
?enforce_private_server_bundles: bool?
73+
) -> void
74+
75+
def setup_config_values: () -> void
76+
77+
private
78+
79+
def check_component_registry_timeout: () -> void
80+
def validate_generated_component_packs_loading_strategy: () -> void
81+
def validate_enforce_private_server_bundles: () -> void
82+
def check_minimum_shakapacker_version: () -> void
83+
def check_autobundling_requirements: () -> void
84+
def adjust_precompile_task: () -> void
85+
def error_if_using_packer_and_generated_assets_dir_not_match_public_output_path: () -> void
86+
def check_server_render_method_is_only_execjs: () -> void
87+
def configure_generated_assets_dirs_deprecation: () -> void
88+
def ensure_webpack_generated_files_exists: () -> void
89+
def configure_skip_display_none_deprecation: () -> void
90+
def raise_missing_components_subdirectory: () -> void
91+
def compile_command_conflict_message: () -> String
92+
end
93+
end

sig/react_on_rails/controller.rbs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module ReactOnRails
2+
module Controller
3+
def redux_store: (
4+
String store_name,
5+
?props: untyped,
6+
?immediate_hydration: bool?
7+
) -> void
8+
9+
def redux_store_hydration_data: () -> String
10+
end
11+
end

sig/react_on_rails/git_utils.rbs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module ReactOnRails
2+
module GitUtils
3+
def self.uncommitted_changes?: (String path) -> bool
4+
def self.git_installed?: () -> bool
5+
def self.current_branch: () -> String?
6+
def self.rspec_fixture_branches: () -> Array[String]
7+
end
8+
end

sig/react_on_rails/helper.rbs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
module ReactOnRails
2+
module Helper
3+
COMPONENT_HTML_KEY: String
4+
5+
# Main helper methods
6+
def react_component: (
7+
String component_name,
8+
?Hash[Symbol, untyped] options
9+
) -> String
10+
11+
def react_component_hash: (
12+
String component_name,
13+
?Hash[Symbol, untyped] options
14+
) -> Hash[String, String]
15+
16+
def redux_store: (
17+
String store_name,
18+
?Hash[Symbol, untyped] props
19+
) -> String
20+
21+
def redux_store_hydration_data: () -> String
22+
23+
def server_render_js: (
24+
String js_expression,
25+
?Hash[Symbol, untyped] options
26+
) -> String
27+
28+
def sanitized_props_string: (untyped props) -> String
29+
30+
def rails_context: (
31+
?server_side: bool
32+
) -> Hash[Symbol, untyped]
33+
34+
private
35+
36+
def internal_react_component: (
37+
String component_name,
38+
Hash[Symbol, untyped] options
39+
) -> Hash[Symbol, untyped]
40+
41+
def build_react_component_result_for_server_rendered_string: (
42+
server_rendered_html: String,
43+
component_specification_tag: String,
44+
console_script: String,
45+
render_options: Hash[Symbol, untyped]
46+
) -> String
47+
48+
def build_react_component_result_for_server_rendered_hash: (
49+
server_rendered_html: Hash[String, untyped],
50+
component_specification_tag: String,
51+
console_script: String,
52+
render_options: Hash[Symbol, untyped]
53+
) -> Hash[String, String]
54+
55+
def prepend_render_rails_context: (String result) -> String
56+
end
57+
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module ReactOnRails
2+
module PackerUtils
3+
def self.supports_autobundling?: () -> bool
4+
def self.supports_basic_pack_generation?: () -> bool
5+
def self.supports_async_loading?: () -> bool
6+
def self.nested_entries?: () -> bool
7+
def self.packer_public_output_path: () -> String
8+
def self.precompile?: () -> bool
9+
def self.shakapacker_precompile_hook_configured?: () -> bool
10+
def self.shakapacker_precompile_hook_value: () -> String
11+
def self.raise_shakapacker_version_incompatible_for_autobundling: () -> void
12+
def self.raise_shakapacker_version_incompatible_for_basic_pack_generation: () -> void
13+
def self.raise_nested_entries_disabled: () -> void
14+
end
15+
end

0 commit comments

Comments
 (0)