react_on_rails_pro 16.2.0.beta.13 → 16.2.0.beta.19

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: 6ea28d8199e9609b3233cd147a173c48936d4400fe618bd609c972bff2fe22a9
4
- data.tar.gz: ab4e291db072282321c49648c0ea4e247f1c69160e6d3bdade1c650ab221d057
3
+ metadata.gz: '0948b2364bf24887f838e2f27fc5ed8b1d8b79bc353501d9d13b05bc1678ad24'
4
+ data.tar.gz: f15f10243f24c7f66211d9cf281428be7657aab395b862110e4ce4b303eaecfd
5
5
  SHA512:
6
- metadata.gz: 86872a77f2b473f5e5e4c36aa7b0809e0e6f26907adfbe6e98b5701e0cfea85c826ab84de90d753c18a03c2b9812672ad9999d418a5abb34995ddaefd2c4b97e
7
- data.tar.gz: 5edffa8cafd674020d4e441b10bb90e2098f1074eadeb2555202e64af238babe8c6ca0d6b55e9ae6c9bda797e7106a28b286416c1b97b691ea28c063e9762126
6
+ metadata.gz: 15850fdf3f3d8b756f213e864ab0d245c7d941fa18d6eae9005cc4f49b8007e73e409a2a748d0e422ddcea504a741cc9d6191dc5d17652736b4ce91b15f5f1dd
7
+ data.tar.gz: 250fb9336012cd4ece659212cd076503d30d7959f148581d16fa26ed32eb09e584dab20272614d44b27afbcd15c489656dbd5289fea969045c4197e66d488aa9
data/.prettierignore CHANGED
@@ -9,3 +9,6 @@ spec/dummy/.yalc/
9
9
 
10
10
  # File Generated by ROR FS-based Registry
11
11
  **/generated
12
+
13
+ # Prettier doesn't understand ERB in RuboCop config
14
+ .rubocop.yml
data/.rubocop.yml CHANGED
@@ -1,111 +1,31 @@
1
- # This is the configuration used to check the rubocop source code.
2
- # Check out: https://github.com/bbatsov/rubocop
3
- require:
4
- - rubocop-performance
5
- - rubocop-rspec
1
+ # Inherits from root config
2
+ inherit_from: ../.rubocop.yml
6
3
 
7
- AllCops:
8
- NewCops: enable
9
- DisplayCopNames: true
10
- TargetRubyVersion: 3.0
11
-
12
- Include:
13
- - '**/Rakefile'
14
- - '**/config.ru'
15
- - 'Gemfile'
16
- - '**/*.rb'
17
- - '**/*.rake'
4
+ # Merge Exclude arrays with parent instead of replacing them
5
+ inherit_mode:
6
+ merge:
7
+ - Exclude
18
8
 
9
+ AllCops:
19
10
  Exclude:
20
11
  <% `git status --ignored --porcelain`.lines.grep(/^!! /).each do |path| %>
21
12
  - <%= path.sub(/^!! /, '') %>
22
13
  <% end %>
23
- - '**/node_modules/**/*'
24
14
  - 'db/schema.rb'
25
15
  - 'db/seeds.rb'
26
- - 'spec/fixtures/**/*'
27
16
  - 'spec/dummy/db/schema.rb'
28
17
  - 'spec/dummy/bin/**/*'
29
- - 'node_modules/**/*'
30
- - 'coverage/**/*'
31
18
  - 'bin/**/*'
32
- - 'vendor/**/*'
33
-
34
- Naming/FileName:
35
- Exclude:
36
- - '**/Gemfile'
37
- - '**/Rakefile'
38
-
39
- Layout/LineLength:
40
- Max: 120
41
-
42
- Style/StringLiterals:
43
- EnforcedStyle: double_quotes
44
-
45
- Style/Documentation:
46
- Enabled: false
47
-
48
- Style/HashEachMethods:
49
- Enabled: true
50
-
51
- Style/HashTransformKeys:
52
- Enabled: true
53
-
54
- Style/HashTransformValues:
55
- Enabled: true
56
-
57
- Metrics/AbcSize:
58
- Max: 28
59
-
60
- Metrics/CyclomaticComplexity:
61
- Max: 8
62
-
63
- Metrics/PerceivedComplexity:
64
- Max: 10
65
-
66
- Metrics/ClassLength:
67
- Max: 140
68
-
69
- Metrics/ParameterLists:
70
- Max: 5
71
- CountKeywordArgs: false
72
-
73
- Metrics/MethodLength:
74
- Max: 41
75
-
76
- Metrics/ModuleLength:
77
- Max: 180
78
-
79
- RSpec/DescribeClass:
80
- Enabled: false
81
-
82
- RSpec/ExampleLength:
83
- Enabled: false
84
-
85
- RSpec/MessageSpies:
86
- Enabled: false
87
-
88
- RSpec/NestedGroups:
89
- Max: 5
90
19
 
91
20
  RSpec/BeforeAfterAll:
92
21
  Exclude:
93
22
  - 'spec/react_on_rails/generators/dev_tests_generator_spec.rb'
94
23
  - 'spec/react_on_rails/generators/install_generator_spec.rb'
95
24
 
96
- RSpec/MessageChain:
97
- Enabled: false
98
-
99
- RSpec/MultipleExpectations:
100
- Enabled: false
101
-
102
25
  RSpec/MultipleDescribes:
103
26
  Exclude:
104
27
  - 'spec/dummy/spec/system/integration_spec.rb'
105
28
 
106
- RSpec/MultipleMemoizedHelpers:
107
- Max: 12
108
-
109
29
  RSpec:
110
30
  Language:
111
31
  Expectations:
@@ -115,6 +35,3 @@ RSpec:
115
35
  Style/GlobalVars:
116
36
  Exclude:
117
37
  - 'spec/dummy/config/environments/development.rb'
118
-
119
- Style/FrozenStringLiteralComment:
120
- EnforcedStyle: always
data/CHANGELOG.md CHANGED
@@ -17,7 +17,9 @@ You can find the **package** version numbers from this repo's tags and below in
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
- _Add changes in master not yet tagged._
20
+ ### [v16.2.0.beta.13] - 2025-12-07
21
+
22
+ Changes since the last non-beta release.
21
23
 
22
24
  ### Improved
23
25
 
@@ -48,8 +50,12 @@ _Add changes in master not yet tagged._
48
50
 
49
51
  ### Fixed
50
52
 
53
+ - **SECURITY: CVE-2025-55182 - React Server Components RCE Vulnerability**: by updating `react-on-rails-rsc` peer dependency to `v19.0.3` which mitigates that vulnerability. Also, users should update `react` and `react-dom` package versions to `v19.0.1` to ensure complete mitigation. [PR 2175](https://github.com/shakacode/react_on_rails/pull/2175) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
54
+
51
55
  - Fixed compatibility issue with httpx 1.6.x by explicitly requiring http-2 >= 1.1.1. [PR 2141](https://github.com/shakacode/react_on_rails/pull/2141) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
52
56
 
57
+ - **Client Disconnect Handling for Streaming**: Added error handling for client disconnects during streaming. When a client disconnects mid-stream (browser closed, network drop), the system now catches `IOError`/`Errno::EPIPE`, sets a `client_disconnected` flag, stops the barrier to cancel producer tasks, and logs the disconnect for debugging. Prevents wasted CPU from producers continuing after the writer fails. [PR 2137](https://github.com/shakacode/react_on_rails/pull/2137) by [justin808](https://github.com/justin808).
58
+
53
59
  - **Node Renderer Worker Restart**: Fixed "descriptor closed" error that occurred when the node renderer restarts while handling an in-progress request (especially streaming requests). Workers now perform graceful shutdowns: they disconnect from the cluster to stop receiving new requests, wait for active requests to complete, then shut down cleanly. A configurable `gracefulWorkerRestartTimeout` ensures workers are forcibly killed if they don't shut down in time. [PR 1970](https://github.com/shakacode/react_on_rails/pull/1970) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
54
60
 
55
61
  - **Body Duplication Bug On Streaming**: Fixed a bug that happens while streaming if the node renderer connection closed after streaming some chunks to the client. [PR 1995](https://github.com/shakacode/react_on_rails/pull/1995) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
@@ -536,7 +542,8 @@ Above changes in [PR 52](https://github.com/shakacode/react_on_rails_pro/pull/52
536
542
  - advanced error handling
537
543
 
538
544
  [HEAD compared to 3.2.1]: https://github.com/shakacode/react_on_rails_pro/compare/3.3.1...HEAD
539
- [Unreleased]: https://github.com/shakacode/react_on_rails_pro/compare/4.0.0-rc-15...HEAD
545
+ [Unreleased]: https://github.com/shakacode/react_on_rails/compare/v16.2.0.beta.13...master
546
+ [v16.2.0.beta.13]: https://github.com/shakacode/react_on_rails/compare/16.1.1...v16.2.0.beta.13
540
547
  [4.0.0-rc.15]: https://github.com/shakacode/react_on_rails_pro/compare/4.0.0-rc.14...4.0.0-rc.15
541
548
  [4.0.0.rc.11]: https://github.com/shakacode/react_on_rails_pro/compare/4.0.0-rc.9...4.0.0-rc.11
542
549
  [4.0.0.rc.9]: https://github.com/shakacode/react_on_rails_pro/compare/4.0.0-rc.6...4.0.0-rc.9
@@ -1,13 +1,16 @@
1
1
  # Keep in sync with https://github.com/shakacode/react_on_rails/blob/master/Gemfile.development_dependencies
2
2
  # frozen_string_literal: true
3
3
 
4
+ # Shared dev dependencies (rubocop, etc.)
5
+ eval_gemfile File.expand_path("../Gemfile.shared_dev_dependencies", __dir__)
6
+
4
7
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
8
 
6
9
  ruby '3.3.7'
7
10
 
8
11
  gem "react_on_rails", path: "../"
9
12
 
10
- gem "shakapacker", "9.3.0"
13
+ gem "shakapacker", "9.4.0"
11
14
  gem "bootsnap", require: false
12
15
  gem "rails", "~> 7.1"
13
16
  gem "puma", "~> 6"
@@ -51,9 +54,6 @@ group :development, :test do
51
54
  gem 'pry-theme' # An easy way to customize Pry colors via theme files
52
55
 
53
56
  gem "rbs", require: false
54
- gem "rubocop", "1.36.0", require: false
55
- gem 'rubocop-performance', "1.15.0", require: false
56
- gem 'rubocop-rspec', "2.13.2", require: false
57
57
  gem "scss_lint", require: false
58
58
  gem 'fakefs', require: 'fakefs/safe'
59
59
  end
data/Gemfile.loader CHANGED
@@ -1,19 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Load base dependencies
4
- base_deps = File.read(File.expand_path("./Gemfile.development_dependencies", __dir__))
4
+ base_deps_path = File.expand_path("./Gemfile.development_dependencies", __dir__)
5
+ base_deps = File.read(base_deps_path)
5
6
 
6
7
  # Determine which override file to use
7
- override_deps = if ENV["CI"] == "true" && File.exist?(File.expand_path("./Gemfile.ci", __dir__))
8
+ override_deps_path = if ENV["CI"] == "true" && File.exist?(File.expand_path("./Gemfile.ci", __dir__))
8
9
  # In CI environment, use CI dependencies
9
- File.read(File.expand_path("./Gemfile.ci", __dir__))
10
+ File.expand_path("./Gemfile.ci", __dir__)
10
11
  elsif File.exist?(File.expand_path("./Gemfile.local", __dir__))
11
12
  # In non-CI environment, use local dependencies if they exist
12
- File.read(File.expand_path("./Gemfile.local", __dir__))
13
- else
14
- ""
13
+ File.expand_path("./Gemfile.local", __dir__)
15
14
  end
16
15
 
16
+ override_deps = override_deps_path ? File.read(override_deps_path) : ""
17
+
17
18
  # Parse override gems
18
19
  override_gem_names = override_deps.scan(/^\s*gem\s+["']([^"']+)["']/).flatten
19
20
 
@@ -26,7 +27,9 @@ end
26
27
  base_deps.gsub!(/^\s*$\n/, '')
27
28
 
28
29
  # Evaluate the modified base dependencies
29
- eval(base_deps)
30
+ # Using instance_eval with filepath preserves __dir__ in evaluated content,
31
+ # allowing eval_gemfile calls to work correctly inside loaded files.
32
+ instance_eval(base_deps, base_deps_path)
30
33
 
31
34
  # Evaluate override dependencies if they exist
32
- eval(override_deps) unless override_deps.empty?
35
+ instance_eval(override_deps, override_deps_path) unless override_deps.empty?
data/Gemfile.lock CHANGED
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: ..
11
11
  specs:
12
- react_on_rails (16.2.0.beta.13)
12
+ react_on_rails (16.2.0.beta.19)
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.2.0.beta.13)
23
+ react_on_rails_pro (16.2.0.beta.19)
24
24
  addressable
25
25
  async (>= 2.6)
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.2.0.beta.13)
32
+ react_on_rails (= 16.2.0.beta.19)
33
33
 
34
34
  GEM
35
35
  remote: https://rubygems.org/
@@ -110,7 +110,7 @@ GEM
110
110
  addressable (2.8.8)
111
111
  public_suffix (>= 2.0.2, < 8.0)
112
112
  amazing_print (1.6.0)
113
- ast (2.4.2)
113
+ ast (2.4.3)
114
114
  async (2.35.0)
115
115
  console (~> 1.29)
116
116
  fiber-annotation
@@ -208,6 +208,7 @@ GEM
208
208
  json (2.17.1)
209
209
  jwt (2.10.2)
210
210
  base64
211
+ language_server-protocol (3.17.0.5)
211
212
  launchy (3.0.1)
212
213
  addressable (~> 2.8)
213
214
  childprocess (~> 5.0)
@@ -252,14 +253,15 @@ GEM
252
253
  nokogiri (1.18.10-x86_64-linux-gnu)
253
254
  racc (~> 1.4)
254
255
  package_json (0.2.0)
255
- parallel (1.25.1)
256
- parser (3.3.3.0)
256
+ parallel (1.27.0)
257
+ parser (3.3.10.0)
257
258
  ast (~> 2.4.1)
258
259
  racc
259
260
  pg (1.5.6)
260
261
  pp (0.6.3)
261
262
  prettyprint
262
263
  prettyprint (0.2.0)
264
+ prism (1.6.0)
263
265
  protocol (2.0.0)
264
266
  ruby_parser (~> 3.0)
265
267
  pry (0.14.2)
@@ -356,23 +358,34 @@ GEM
356
358
  rspec-support (3.13.1)
357
359
  rspec_junit_formatter (0.6.0)
358
360
  rspec-core (>= 2, < 4, != 2.12.0)
359
- rubocop (1.36.0)
361
+ rubocop (1.61.0)
360
362
  json (~> 2.3)
363
+ language_server-protocol (>= 3.17.0)
361
364
  parallel (~> 1.10)
362
- parser (>= 3.1.2.1)
365
+ parser (>= 3.3.0.2)
363
366
  rainbow (>= 2.2.2, < 4.0)
364
367
  regexp_parser (>= 1.8, < 3.0)
365
368
  rexml (>= 3.2.5, < 4.0)
366
- rubocop-ast (>= 1.20.1, < 2.0)
369
+ rubocop-ast (>= 1.30.0, < 2.0)
367
370
  ruby-progressbar (~> 1.7)
368
- unicode-display_width (>= 1.4.0, < 3.0)
369
- rubocop-ast (1.31.3)
370
- parser (>= 3.3.1.0)
371
- rubocop-performance (1.15.0)
372
- rubocop (>= 1.7.0, < 2.0)
373
- rubocop-ast (>= 0.4.0)
374
- rubocop-rspec (2.13.2)
375
- rubocop (~> 1.33)
371
+ unicode-display_width (>= 2.4.0, < 3.0)
372
+ rubocop-ast (1.48.0)
373
+ parser (>= 3.3.7.2)
374
+ prism (~> 1.4)
375
+ rubocop-capybara (2.21.0)
376
+ rubocop (~> 1.41)
377
+ rubocop-factory_bot (2.26.1)
378
+ rubocop (~> 1.61)
379
+ rubocop-performance (1.20.2)
380
+ rubocop (>= 1.48.1, < 2.0)
381
+ rubocop-ast (>= 1.30.0, < 2.0)
382
+ rubocop-rspec (2.31.0)
383
+ rubocop (~> 1.40)
384
+ rubocop-capybara (~> 2.17)
385
+ rubocop-factory_bot (~> 2.22)
386
+ rubocop-rspec_rails (~> 2.28)
387
+ rubocop-rspec_rails (2.29.1)
388
+ rubocop (~> 1.61)
376
389
  ruby-progressbar (1.13.0)
377
390
  ruby_parser (3.21.0)
378
391
  racc (~> 1.5)
@@ -402,7 +415,7 @@ GEM
402
415
  websocket (~> 1.0)
403
416
  semantic_range (3.1.0)
404
417
  sexp_processor (4.17.1)
405
- shakapacker (9.3.0)
418
+ shakapacker (9.4.0)
406
419
  activesupport (>= 5.2)
407
420
  package_json
408
421
  rack-proxy (>= 0.6.1)
@@ -447,7 +460,7 @@ GEM
447
460
  concurrent-ruby (~> 1.0)
448
461
  uglifier (4.2.0)
449
462
  execjs (>= 0.3.0, < 3)
450
- unicode-display_width (2.5.0)
463
+ unicode-display_width (2.6.0)
451
464
  uri (1.0.3)
452
465
  useragent (0.16.11)
453
466
  web-console (4.2.1)
@@ -513,13 +526,13 @@ DEPENDENCIES
513
526
  rspec-rails
514
527
  rspec-retry
515
528
  rspec_junit_formatter
516
- rubocop (= 1.36.0)
517
- rubocop-performance (= 1.15.0)
518
- rubocop-rspec (= 2.13.2)
529
+ rubocop (= 1.61.0)
530
+ rubocop-performance (~> 1.20.0)
531
+ rubocop-rspec (~> 2.26)
519
532
  sass-rails
520
533
  scss_lint
521
534
  selenium-webdriver (= 4.9.0)
522
- shakapacker (= 9.3.0)
535
+ shakapacker (= 9.4.0)
523
536
  spring
524
537
  spring-watcher-listen
525
538
  sprockets
@@ -1,12 +1,14 @@
1
1
  # Server-side rendering with code-splitting using Loadable/Components
2
+
2
3
  by ShakaCode
3
4
 
4
- *Last updated September 19, 2022*
5
+ _Last updated September 19, 2022_
5
6
 
6
7
  ## Introduction
8
+
7
9
  The [React library recommends](https://loadable-components.com/docs/getting-started/) the use of React.lazy for code splitting with dynamic imports except
8
10
  when using server-side rendering. In that case, as of February 2020, they recommend [Loadable Components](https://loadable-components.com)
9
- for server-side rendering with dynamic imports.
11
+ for server-side rendering with dynamic imports.
10
12
 
11
13
  Note, in 2019 and prior, the code-splitting feature was implemented using `react-loadable`. The React
12
14
  team no longer recommends that library. The new way is far preferable.
@@ -18,7 +20,8 @@ yarn add @loadable/babel-plugin @loadable/component @loadable/server @loadable/
18
20
  ```
19
21
 
20
22
  ### Summary
21
- - [`@loadable/babel-plugin`](https://loadable-components.com/docs/getting-started/) - The plugin transforms your code to be ready for Server Side Rendering.
23
+
24
+ - [`@loadable/babel-plugin`](https://loadable-components.com/docs/getting-started/) - The plugin transforms your code to be ready for Server Side Rendering.
22
25
  - `@loadable/component` - Main library for creating loadable components.
23
26
  - `@loadable/server` - Has functions for collecting chunks and provide style, script, link tags for the server.
24
27
  - `@loadable/webpack-plugin` - The plugin to create a stats file with all chunks, assets information.
@@ -35,15 +38,16 @@ See example of server configuration differences in the loadable-components [exam
35
38
  for server-side rendering](https://github.com/gregberge/loadable-components/blob/master/examples/server-side-rendering/webpack.config.babel.js)
36
39
 
37
40
  You need to configure 3 things:
38
- 1. `target`
39
- a. client-side: `web`
40
- b. server-side: `node`
41
+
42
+ 1. `target`
43
+ a. client-side: `web`
44
+ b. server-side: `node`
41
45
  2. `output.libraryTarget`
42
- a. client-side: `undefined`
43
- b. server-side: `commonjs2`
44
- 3. babel-loader options.caller = 'node' or 'web'
45
- 3. `plugins`
46
- a. server-side: `new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })`
46
+ a. client-side: `undefined`
47
+ b. server-side: `commonjs2`
48
+ 3. babel-loader options.caller = 'node' or 'web'
49
+ 4. `plugins`
50
+ a. server-side: `new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })`
47
51
 
48
52
  ```js
49
53
  {
@@ -58,14 +62,15 @@ You need to configure 3 things:
58
62
  Explanation:
59
63
 
60
64
  - `target: 'node'` is required to be able to run the server bundle with the dynamic import logic on nodejs.
61
- If that is not done, webpack will add and invoke browser-specific functions to fetch the chunks into the bundle, which throws an error on server-rendering.
65
+ If that is not done, webpack will add and invoke browser-specific functions to fetch the chunks into the bundle, which throws an error on server-rendering.
62
66
 
63
67
  - `new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })`
64
- The react_on_rails_pro node-renderer expects only one single server-bundle. In other words, we cannot and do not want to split the server bundle.
68
+ The react_on_rails_pro node-renderer expects only one single server-bundle. In other words, we cannot and do not want to split the server bundle.
65
69
 
66
70
  #### Client config
67
71
 
68
72
  For the client config we only need to add the plugin:
73
+
69
74
  ```js
70
75
  {
71
76
  plugins: [
@@ -74,30 +79,33 @@ For the client config we only need to add the plugin:
74
79
  ]
75
80
  }
76
81
  ```
82
+
77
83
  This plugin collects all the information about entrypoints, chunks, and files, that have these chunks and creates a stats file during client bundle build.
78
84
  This stats file is used later to map rendered components to file assets. While you can use any filename, our documentation will use the default name.
79
85
 
80
86
  ### Babel
81
87
 
82
88
  Per [the docs](https://loadable-components.com/docs/babel-plugin/#transformation):
89
+
83
90
  > The plugin transforms your code to be ready for Server Side Rendering
84
91
 
85
92
  Add this to `babel.config.js`:
93
+
86
94
  ```js
87
95
  {
88
96
  "plugins": ["@loadable/babel-plugin"]
89
97
  }
90
98
  ```
91
- https://loadable-components.com/docs/babel-plugin/
92
99
 
100
+ https://loadable-components.com/docs/babel-plugin/
93
101
 
94
102
  ### Convert components into loadable components
95
103
 
96
104
  Instead of importing the component directly, use a dynamic import:
97
105
 
98
106
  ```js
99
- import load from '@loadable/component'
100
- const MyComponent = load(() => import('./MyComponent'))
107
+ import load from '@loadable/component';
108
+ const MyComponent = load(() => import('./MyComponent'));
101
109
  ```
102
110
 
103
111
  ### Resolving issue with ChunkLoadError
@@ -118,22 +126,25 @@ const consoleDebug = (fn) => {
118
126
  console.debug(fn());
119
127
  }
120
128
  };
121
- const retry = (fn, retryMessage = '', retriesLeft = 3, interval = 500) => new Promise((resolve, reject) => {
122
- fn()
123
- .then(resolve)
124
- .catch(() => {
125
- setTimeout(() => {
126
- if (retriesLeft === 1) {
127
- console.warn(`Maximum retries exceeded, retryMessage: ${retryMessage}. Reloading page...`);
128
- window.location.reload();
129
- return;
130
- }
131
- // Passing on "reject" is the important part
132
- consoleDebug(() => `Trying request, retryMessage: ${retryMessage}, retriesLeft: ${retriesLeft - 1}`);
133
- retry(fn, retryMessage, retriesLeft - 1, interval).then(resolve, reject);
134
- }, interval);
135
- });
136
- });
129
+ const retry = (fn, retryMessage = '', retriesLeft = 3, interval = 500) =>
130
+ new Promise((resolve, reject) => {
131
+ fn()
132
+ .then(resolve)
133
+ .catch(() => {
134
+ setTimeout(() => {
135
+ if (retriesLeft === 1) {
136
+ console.warn(`Maximum retries exceeded, retryMessage: ${retryMessage}. Reloading page...`);
137
+ window.location.reload();
138
+ return;
139
+ }
140
+ // Passing on "reject" is the important part
141
+ consoleDebug(
142
+ () => `Trying request, retryMessage: ${retryMessage}, retriesLeft: ${retriesLeft - 1}`,
143
+ );
144
+ retry(fn, retryMessage, retriesLeft - 1, interval).then(resolve, reject);
145
+ }, interval);
146
+ });
147
+ });
137
148
  export default retry;
138
149
  ```
139
150
 
@@ -152,21 +163,21 @@ const HomePage = loadable(() => retry(() => import('./HomePage')));
152
163
 
153
164
  In the client bundle, we need to wrap the `hydrateRoot` call into a `loadableReady` function.
154
165
  So, hydration will be fired only after all necessary chunks preloads. In this example below,
155
- `ClientApp` is registering as `App`.
166
+ `ClientApp` is registering as `App`.
156
167
 
157
168
  ```js
158
169
  import React from 'react';
159
170
  import ReactOnRails from 'react-on-rails';
160
- import { hydrateRoot } from 'react-dom/client'
161
- import { loadableReady } from '@loadable/component'
171
+ import { hydrateRoot } from 'react-dom/client';
172
+ import { loadableReady } from '@loadable/component';
162
173
  import App from './App';
163
174
 
164
175
  const ClientApp = (props, railsContext, domId) => {
165
176
  loadableReady(() => {
166
- const root = document.getElementById(domId)
177
+ const root = document.getElementById(domId);
167
178
  hydrateRoot(root, <App {...props} />);
168
- })
169
- }
179
+ });
180
+ };
170
181
 
171
182
  ReactOnRails.register({
172
183
  App: ClientApp,
@@ -175,20 +186,20 @@ ReactOnRails.register({
175
186
 
176
187
  #### Server
177
188
 
178
- The purpose of the server function is to collect all rendered chunks and pass them as script, link,
179
- style tags to the Rails view. In this example below, `ServerApp` is registering as `App`.
189
+ The purpose of the server function is to collect all rendered chunks and pass them as script, link,
190
+ style tags to the Rails view. In this example below, `ServerApp` is registering as `App`.
180
191
 
181
192
  ```js
182
193
  import React from 'react';
183
194
  import ReactOnRails from 'react-on-rails';
184
- import { ChunkExtractor } from '@loadable/server'
185
- import App from './App'
186
- import path from 'path'
195
+ import { ChunkExtractor } from '@loadable/server';
196
+ import App from './App';
197
+ import path from 'path';
187
198
 
188
199
  const ServerApp = (props, railsContext) => {
189
200
  // This loadable-stats file was generated by `LoadablePlugin` in client webpack config.
190
201
  // You must configure the path to resolve per your setup. If you are copying the file to
191
- // a remote server, the file should be a sibling of this file.
202
+ // a remote server, the file should be a sibling of this file.
192
203
  // __dirname is going to be the directory where the server-bundle.js exists
193
204
  // Note, React on Rails Pro automatically copies the loadable-stats.json to the same place as the
194
205
  // server-bundle.js. Thus, the __dirname of this code is where we can find loadable-stats.json.
@@ -198,10 +209,10 @@ const ServerApp = (props, railsContext) => {
198
209
  // This object is used to search filenames by corresponding chunk names.
199
210
  // See https://loadable-components.com/docs/api-loadable-server/#chunkextractor
200
211
  // for the entryPoints, pass an array of all your entryPoints using dynamic imports
201
- const extractor = new ChunkExtractor({ statsFile, entrypoints: ['client-bundle'] })
212
+ const extractor = new ChunkExtractor({ statsFile, entrypoints: ['client-bundle'] });
202
213
 
203
214
  // It creates the wrapper `ChunkExtractorManager` around `App` to collect chunk names of rendered components.
204
- const jsx = extractor.collectChunks(<App {...props} railsContext={railsContext} />)
215
+ const jsx = extractor.collectChunks(<App {...props} railsContext={railsContext} />);
205
216
 
206
217
  const componentHtml = renderToString(jsx);
207
218
 
@@ -211,8 +222,8 @@ const ServerApp = (props, railsContext) => {
211
222
  // Returns all the files with rendered chunks for furture insert into rails view.
212
223
  linkTags: extractor.getLinkTags(),
213
224
  styleTags: extractor.getStyleTags(),
214
- scriptTags: extractor.getScriptTags()
215
- }
225
+ scriptTags: extractor.getScriptTags(),
226
+ },
216
227
  };
217
228
  };
218
229
 
@@ -224,6 +235,7 @@ ReactOnRails.register({
224
235
  ## Configure react_on_rails_pro
225
236
 
226
237
  ### React on Rails Pro
238
+
227
239
  You must set `config.assets_top_copy` so that the node-renderer will have access to the loadable-stats.json.
228
240
 
229
241
  ```ruby
@@ -233,15 +245,16 @@ You must set `config.assets_top_copy` so that the node-renderer will have access
233
245
  Your server rendering code, per the above, will find this file like this:
234
246
 
235
247
  ```js
236
- const statsFile = path.resolve(__dirname, 'loadable-stats.json');
237
- ```
248
+ const statsFile = path.resolve(__dirname, 'loadable-stats.json');
249
+ ```
238
250
 
239
251
  Note, if `__dirname` is not working in your webpack build, that's because you didn't set `node: false`
240
252
  in your webpack configuration. That turns off the polyfills for things like `__dirname`.
241
253
 
242
-
243
254
  ### Node Renderer
255
+
244
256
  In your `node-renderer.js` file which runs node renderer, you need to specify `supportModules` options as follows:
257
+
245
258
  ```js
246
259
  const path = require('path');
247
260
  const env = process.env;
@@ -261,7 +274,7 @@ reactOnRailsProNodeRenderer(config);
261
274
  ```erb
262
275
  <% res = react_component_hash("App", props: {}, prerender: true) %>
263
276
  <%= content_for :link_tags, res['linkTags'] %>
264
- <%= content_for :style_tags, res['styleTags'] %>
277
+ <%= content_for :style_tags, res['styleTags'] %>
265
278
 
266
279
  <%= res['componentHtml'].html_safe %>
267
280
 
@@ -269,6 +282,7 @@ reactOnRailsProNodeRenderer(config);
269
282
  ```
270
283
 
271
284
  ## Making HMR Work
285
+
272
286
  To make HMR work, it's best to disable loadable-components when using the Dev Server.
273
287
  Note: you will need access to our **private** React on Rails Pro repository to open the following links.
274
288
 
@@ -277,9 +291,11 @@ Take a look at the code searches for ['imports-loadable'](https://github.com/sha
277
291
  The general concept is that we have a non-loadable, HMR-ready, file that substitutes for the loadable-enabled one, with the suffixes `imports-hmr.js` instead of `imports-loadable.js`
278
292
 
279
293
  ### Webpack configuration
294
+
280
295
  Use the [NormalModuleReplacement plugin](https://webpack.js.org/plugins/normal-module-replacement-plugin/):
281
296
 
282
297
  [code](https://github.com/shakacode/react_on_rails_pro/blob/a361f4e163b9170f180ae07ee312fb9b4c719fc3/spec/dummy/config/webpack/environment.js#L81-L91)
298
+
283
299
  ```js
284
300
  if (isWebpackDevServer) {
285
301
  environment.plugins.append(
@@ -305,7 +321,7 @@ Note: you will need access to our **private** React on Rails Pro repository to o
305
321
  ### Client-Side Startup
306
322
 
307
323
  - [spec/dummy/client/app/loadable/loadable-client.imports-hmr.js](https://github.com/shakacode/react_on_rails_pro/blob/master/spec/dummy/client/app/loadable/loadable-client.imports-hmr.js)
308
- - [spec/dummy/client/app/loadable/loadable-client.imports-loadable.js](https://github.com/shakacode/react_on_rails_pro/blob/master/spec/dummy/client/app/loadable/loadable-client.imports-loadable.js)
324
+ - [spec/dummy/client/app/loadable/loadable-client.imports-loadable.jsx](https://github.com/shakacode/react_on_rails_pro/blob/master/spec/dummy/client/app/loadable/loadable-client.imports-loadable.jsx)
309
325
 
310
326
  ### Server-Side Startup
311
327
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRailsPro
4
- VERSION = "16.2.0.beta.13"
4
+ VERSION = "16.2.0.beta.19"
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.2.0.beta.13
4
+ version: 16.2.0.beta.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-12-07 00:00:00.000000000 Z
11
+ date: 2025-12-11 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.2.0.beta.13
131
+ version: 16.2.0.beta.19
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.2.0.beta.13
138
+ version: 16.2.0.beta.19
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: bundler
141
141
  requirement: !ruby/object:Gem::Requirement