react_on_rails 16.2.0.beta.4 → 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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -8
  3. data/CONTRIBUTING.md +1 -1
  4. data/Gemfile.development_dependencies +0 -1
  5. data/Gemfile.lock +1 -9
  6. data/bin/ci-rerun-failures +39 -16
  7. data/bin/ci-run-failed-specs +1 -1
  8. data/bin/ci-switch-config +8 -2
  9. data/bin/lefthook/ruby-autofix +2 -1
  10. data/knip.ts +35 -9
  11. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt +32 -52
  12. data/lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml +5 -1
  13. data/lib/react_on_rails/dev/server_manager.rb +11 -4
  14. data/lib/react_on_rails/doctor.rb +245 -0
  15. data/lib/react_on_rails/helper.rb +9 -0
  16. data/lib/react_on_rails/version.rb +1 -1
  17. data/react_on_rails_pro/CHANGELOG.md +7 -0
  18. data/react_on_rails_pro/CONTRIBUTING.md +2 -13
  19. data/react_on_rails_pro/Gemfile.lock +21 -3
  20. data/react_on_rails_pro/docs/code-splitting-loadable-components.md +1 -1
  21. data/react_on_rails_pro/docs/contributors-info/releasing.md +2 -2
  22. data/react_on_rails_pro/docs/installation.md +106 -104
  23. data/react_on_rails_pro/docs/node-renderer/basics.md +3 -3
  24. data/react_on_rails_pro/docs/node-renderer/error-reporting-and-tracing.md +8 -8
  25. data/react_on_rails_pro/docs/node-renderer/js-configuration.md +1 -1
  26. data/react_on_rails_pro/docs/updating.md +209 -15
  27. data/react_on_rails_pro/lib/react_on_rails_pro/concerns/stream.rb +58 -4
  28. data/react_on_rails_pro/lib/react_on_rails_pro/configuration.rb +17 -3
  29. data/react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb +9 -9
  30. data/react_on_rails_pro/lib/react_on_rails_pro/request.rb +41 -25
  31. data/react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb +27 -7
  32. data/react_on_rails_pro/lib/react_on_rails_pro/utils.rb +3 -3
  33. data/react_on_rails_pro/lib/react_on_rails_pro/version.rb +1 -1
  34. data/react_on_rails_pro/package-scripts.yml +1 -1
  35. data/react_on_rails_pro/package.json +5 -8
  36. data/react_on_rails_pro/packages/node-renderer/src/integrations/api.ts +1 -1
  37. data/react_on_rails_pro/rakelib/public_key_management.rake +6 -5
  38. data/react_on_rails_pro/react_on_rails_pro.gemspec +1 -0
  39. data/react_on_rails_pro/spec/dummy/Gemfile.lock +20 -3
  40. data/react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb +3 -3
  41. data/react_on_rails_pro/spec/dummy/bin/dev +4 -8
  42. data/react_on_rails_pro/spec/dummy/client/node-renderer.js +3 -3
  43. data/react_on_rails_pro/spec/dummy/config/environments/production.rb +1 -1
  44. data/react_on_rails_pro/spec/dummy/config/initializers/react_on_rails.rb +28 -12
  45. data/react_on_rails_pro/spec/dummy/config.ru +1 -1
  46. data/react_on_rails_pro/spec/dummy/package.json +2 -2
  47. data/react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb +40 -11
  48. data/react_on_rails_pro/spec/dummy/spec/rails_helper.rb +1 -1
  49. data/react_on_rails_pro/spec/dummy/spec/requests/renderer_console_logging_spec.rb +5 -5
  50. data/react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb +20 -14
  51. data/react_on_rails_pro/spec/dummy/spec/system/renderer_integration_spec.rb +3 -3
  52. data/react_on_rails_pro/spec/dummy/yarn.lock +4 -4
  53. data/react_on_rails_pro/spec/execjs-compatible-dummy/config/environments/production.rb +1 -1
  54. data/react_on_rails_pro/spec/execjs-compatible-dummy/config/initializers/react_on_rails.rb +16 -43
  55. data/react_on_rails_pro/spec/react_on_rails_pro/assets_precompile_spec.rb +15 -18
  56. data/react_on_rails_pro/spec/react_on_rails_pro/cache_spec.rb +1 -1
  57. data/react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb +5 -3
  58. data/react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb +27 -12
  59. data/react_on_rails_pro/spec/react_on_rails_pro/request_spec.rb +0 -27
  60. data/react_on_rails_pro/spec/react_on_rails_pro/spec_helper.rb +1 -1
  61. data/react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb +89 -0
  62. data/react_on_rails_pro/spec/react_on_rails_pro/stream_spec.rb +144 -0
  63. data/react_on_rails_pro/spec/react_on_rails_pro/support/caching.rb +1 -1
  64. data/react_on_rails_pro/spec/react_on_rails_pro/support/mock_block_helper.rb +4 -2
  65. metadata +2 -3
  66. data/react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/TestingStreamableComponent.jsx +0 -15
@@ -38,12 +38,66 @@ module ReactOnRailsPro
38
38
  # So we strip extra newlines from the template string and add a single newline
39
39
  response.stream.write(template_string)
40
40
 
41
- @rorp_rendering_fibers.each do |fiber|
42
- while (chunk = fiber.resume)
43
- response.stream.write(chunk)
41
+ begin
42
+ drain_streams_concurrently
43
+ ensure
44
+ response.stream.close if close_stream_at_end
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def drain_streams_concurrently
51
+ require "async"
52
+ require "async/limited_queue"
53
+
54
+ return if @rorp_rendering_fibers.empty?
55
+
56
+ Sync do |parent|
57
+ # To avoid memory bloat, we use a limited queue to buffer chunks in memory.
58
+ buffer_size = ReactOnRailsPro.configuration.concurrent_component_streaming_buffer_size
59
+ queue = Async::LimitedQueue.new(buffer_size)
60
+
61
+ writer = build_writer_task(parent: parent, queue: queue)
62
+ tasks = build_producer_tasks(parent: parent, queue: queue)
63
+
64
+ # This structure ensures that even if a producer task fails, we always
65
+ # signal the writer to stop and then wait for it to finish draining
66
+ # any remaining items from the queue before propagating the error.
67
+ begin
68
+ tasks.each(&:wait)
69
+ ensure
70
+ # `close` signals end-of-stream; when writer tries to dequeue, it will get nil, so it will exit.
71
+ queue.close
72
+ writer.wait
73
+ end
74
+ end
75
+ end
76
+
77
+ def build_producer_tasks(parent:, queue:)
78
+ @rorp_rendering_fibers.each_with_index.map do |fiber, idx|
79
+ parent.async do
80
+ loop do
81
+ chunk = fiber.resume
82
+ break unless chunk
83
+
84
+ # Will be blocked if the queue is full until a chunk is dequeued
85
+ queue.enqueue([idx, chunk])
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ def build_writer_task(parent:, queue:)
92
+ parent.async do
93
+ loop do
94
+ pair = queue.dequeue
95
+ break if pair.nil?
96
+
97
+ _idx_from_queue, item = pair
98
+ response.stream.write(item)
44
99
  end
45
100
  end
46
- response.stream.close if close_stream_at_end
47
101
  end
48
102
  end
49
103
  end
@@ -32,7 +32,8 @@ module ReactOnRailsPro
32
32
  rsc_payload_generation_url_path: Configuration::DEFAULT_RSC_PAYLOAD_GENERATION_URL_PATH,
33
33
  rsc_bundle_js_file: Configuration::DEFAULT_RSC_BUNDLE_JS_FILE,
34
34
  react_client_manifest_file: Configuration::DEFAULT_REACT_CLIENT_MANIFEST_FILE,
35
- react_server_client_manifest_file: Configuration::DEFAULT_REACT_SERVER_CLIENT_MANIFEST_FILE
35
+ react_server_client_manifest_file: Configuration::DEFAULT_REACT_SERVER_CLIENT_MANIFEST_FILE,
36
+ concurrent_component_streaming_buffer_size: Configuration::DEFAULT_CONCURRENT_COMPONENT_STREAMING_BUFFER_SIZE
36
37
  )
37
38
  end
38
39
 
@@ -59,6 +60,7 @@ module ReactOnRailsPro
59
60
  DEFAULT_RSC_BUNDLE_JS_FILE = "rsc-bundle.js"
60
61
  DEFAULT_REACT_CLIENT_MANIFEST_FILE = "react-client-manifest.json"
61
62
  DEFAULT_REACT_SERVER_CLIENT_MANIFEST_FILE = "react-server-client-manifest.json"
63
+ DEFAULT_CONCURRENT_COMPONENT_STREAMING_BUFFER_SIZE = 64
62
64
 
63
65
  attr_accessor :renderer_url, :renderer_password, :tracing,
64
66
  :server_renderer, :renderer_use_fallback_exec_js, :prerender_caching,
@@ -68,7 +70,7 @@ module ReactOnRailsPro
68
70
  :renderer_request_retry_limit, :throw_js_errors, :ssr_timeout,
69
71
  :profile_server_rendering_js_code, :raise_non_shell_server_rendering_errors, :enable_rsc_support,
70
72
  :rsc_payload_generation_url_path, :rsc_bundle_js_file, :react_client_manifest_file,
71
- :react_server_client_manifest_file
73
+ :react_server_client_manifest_file, :concurrent_component_streaming_buffer_size
72
74
 
73
75
  def initialize(renderer_url: nil, renderer_password: nil, server_renderer: nil, # rubocop:disable Metrics/AbcSize
74
76
  renderer_use_fallback_exec_js: nil, prerender_caching: nil,
@@ -79,7 +81,9 @@ module ReactOnRailsPro
79
81
  renderer_request_retry_limit: nil, throw_js_errors: nil, ssr_timeout: nil,
80
82
  profile_server_rendering_js_code: nil, raise_non_shell_server_rendering_errors: nil,
81
83
  enable_rsc_support: nil, rsc_payload_generation_url_path: nil,
82
- rsc_bundle_js_file: nil, react_client_manifest_file: nil, react_server_client_manifest_file: nil)
84
+ rsc_bundle_js_file: nil, react_client_manifest_file: nil,
85
+ react_server_client_manifest_file: nil,
86
+ concurrent_component_streaming_buffer_size: DEFAULT_CONCURRENT_COMPONENT_STREAMING_BUFFER_SIZE)
83
87
  self.renderer_url = renderer_url
84
88
  self.renderer_password = renderer_password
85
89
  self.server_renderer = server_renderer
@@ -105,6 +109,7 @@ module ReactOnRailsPro
105
109
  self.rsc_bundle_js_file = rsc_bundle_js_file
106
110
  self.react_client_manifest_file = react_client_manifest_file
107
111
  self.react_server_client_manifest_file = react_server_client_manifest_file
112
+ self.concurrent_component_streaming_buffer_size = concurrent_component_streaming_buffer_size
108
113
  end
109
114
 
110
115
  def setup_config_values
@@ -113,6 +118,7 @@ module ReactOnRailsPro
113
118
  validate_remote_bundle_cache_adapter
114
119
  setup_renderer_password
115
120
  setup_assets_to_copy
121
+ validate_concurrent_component_streaming_buffer_size
116
122
  setup_execjs_profiler_if_needed
117
123
  check_react_on_rails_support_for_rsc
118
124
  end
@@ -204,6 +210,14 @@ module ReactOnRailsPro
204
210
  end
205
211
  end
206
212
 
213
+ def validate_concurrent_component_streaming_buffer_size
214
+ return if concurrent_component_streaming_buffer_size.is_a?(Integer) &&
215
+ concurrent_component_streaming_buffer_size.positive?
216
+
217
+ raise ReactOnRailsPro::Error,
218
+ "config.concurrent_component_streaming_buffer_size must be a positive integer"
219
+ end
220
+
207
221
  def setup_renderer_password
208
222
  return if renderer_password.present?
209
223
 
@@ -16,15 +16,15 @@ module ReactOnRailsPro
16
16
  # TODO: Add a prepublish check to ensure this key matches the latest public key from the API.
17
17
  # This should be implemented after publishing the API endpoint on the ShakaCode website.
18
18
  KEY = OpenSSL::PKey::RSA.new(<<~PEM.strip.strip_heredoc)
19
- -----BEGIN PUBLIC KEY-----
20
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcS/fpHz5CbnTQxb4Zot
21
- khjzXu7xNS+Y9VKfapMaHOMzNoCMfy1++hxHJatRedr+YQfZRCjfiN168Cpe+dhe
22
- yfNtOoLU9/+/5jTsxH+WQJWNRswyKms5HNajlIMN1GEYdZmZbvOPaZvh6ENsT+EV
23
- HnhjJtsHl7qltBoL0ul7rONxaNHCzJcKk4lf3B2/1j1wpA91MKz4bbQVh4/6Th0E
24
- /39f0PWvvBXzQS+yt1qaa1DIX5YL6Aug5uEpb1+6QWcN3hCzqSPBv1HahrG50rsD
25
- gf8KORV3X2N9t6j6iqPmRqfRcTBKtmPhM9bORtKiSwBK8LsIUzp2/UUmkdHnkyzu
26
- NQIDAQAB
27
- -----END PUBLIC KEY-----
19
+ -----BEGIN PUBLIC KEY-----
20
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcS/fpHz5CbnTQxb4Zot
21
+ khjzXu7xNS+Y9VKfapMaHOMzNoCMfy1++hxHJatRedr+YQfZRCjfiN168Cpe+dhe
22
+ yfNtOoLU9/+/5jTsxH+WQJWNRswyKms5HNajlIMN1GEYdZmZbvOPaZvh6ENsT+EV
23
+ HnhjJtsHl7qltBoL0ul7rONxaNHCzJcKk4lf3B2/1j1wpA91MKz4bbQVh4/6Th0E
24
+ /39f0PWvvBXzQS+yt1qaa1DIX5YL6Aug5uEpb1+6QWcN3hCzqSPBv1HahrG50rsD
25
+ gf8KORV3X2N9t6j6iqPmRqfRcTBKtmPhM9bORtKiSwBK8LsIUzp2/UUmkdHnkyzu
26
+ NQIDAQAB
27
+ -----END PUBLIC KEY-----
28
28
  PEM
29
29
  end
30
30
  end
@@ -9,9 +9,7 @@ module ReactOnRailsPro
9
9
  class << self
10
10
  def reset_connection
11
11
  @connection&.close
12
- @connection_without_retries&.close
13
12
  @connection = create_connection
14
- @connection_without_retries = create_connection(enable_retries: false)
15
13
  end
16
14
 
17
15
  def render_code(path, js_code, send_bundle)
@@ -84,29 +82,17 @@ module ReactOnRailsPro
84
82
 
85
83
  private
86
84
 
87
- # NOTE: We maintain two separate HTTP connection pools to handle streaming vs non-streaming requests.
88
- # This doubles the memory footprint (e.g., if renderer_http_pool_size is 10, we use 20 total connections).
89
- # This tradeoff is acceptable to prevent body duplication in streaming responses.
90
-
91
85
  def connection
92
86
  @connection ||= create_connection
93
87
  end
94
88
 
95
- def connection_without_retries
96
- @connection_without_retries ||= create_connection(enable_retries: false)
97
- end
98
-
99
- def perform_request(path, **post_options) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
100
- # For streaming requests, use connection without retries to prevent body duplication
101
- # The StreamRequest class handles retries properly by starting fresh requests
102
- conn = post_options[:stream] ? connection_without_retries : connection
103
-
89
+ def perform_request(path, **post_options) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
104
90
  available_retries = ReactOnRailsPro.configuration.renderer_request_retry_limit
105
91
  retry_request = true
106
92
  while retry_request
107
93
  begin
108
94
  start_time = Time.now
109
- response = conn.post(path, **post_options)
95
+ response = connection.post(path, **post_options)
110
96
  raise response.error if response.is_a?(HTTPX::ErrorResponse)
111
97
 
112
98
  request_time = Time.now - start_time
@@ -231,20 +217,50 @@ module ReactOnRailsPro
231
217
  ReactOnRailsPro::Utils.common_form_data
232
218
  end
233
219
 
234
- def create_connection(enable_retries: true)
220
+ def create_connection # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
235
221
  url = ReactOnRailsPro.configuration.renderer_url
236
222
  Rails.logger.info do
237
223
  "[ReactOnRailsPro] Setting up Node Renderer connection to #{url}"
238
224
  end
239
225
 
240
- http_client = HTTPX
241
- # For persistent connections we want retries,
242
- # so the requests don't just fail if the other side closes the connection
243
- # https://honeyryderchuck.gitlab.io/httpx/wiki/Persistent
244
- # However, for streaming requests, retries cause body duplication
245
- # See https://github.com/shakacode/react_on_rails/issues/1895
246
- http_client = http_client.plugin(:retries, max_retries: 1, retry_change_requests: true) if enable_retries
247
- http_client
226
+ HTTPX
227
+ # For persistent connections we want retries,
228
+ # so the requests don't just fail if the other side closes the connection
229
+ # https://honeyryderchuck.gitlab.io/httpx/wiki/Persistent
230
+ .plugin(
231
+ :retries, max_retries: 1,
232
+ retry_change_requests: true,
233
+ # Official HTTPx docs says that we should use the retry_on option to decide if the
234
+ # request should be retried or not
235
+ # However, HTTPx assumes that connection errors such as timeout error should be retried
236
+ # by default and it doesn't consider retry_on block at all at that case
237
+ # So, we have to do the following trick to avoid retries when a Timeout error happens
238
+ # while streaming a component
239
+ # If the streamed component returned any chunks, it shouldn't retry on errors, as it
240
+ # would cause page duplication
241
+ # The SSR-generated html will be written to the page two times in this case
242
+ retry_after: lambda do |request, response|
243
+ if request.stream.instance_variable_get(:@react_on_rails_received_first_chunk)
244
+ e = response.error
245
+ raise(
246
+ ReactOnRailsPro::Error,
247
+ "An error happened during server side render streaming " \
248
+ "of a component.\nOriginal error:\n#{e}\n#{e.backtrace}"
249
+ )
250
+ end
251
+
252
+ Rails.logger.info do
253
+ "[ReactOnRailsPro] An error occurred while making " \
254
+ "a request to the Node Renderer.\n" \
255
+ "Error: #{response.error}.\n" \
256
+ "Retrying by HTTPX \"retries\" plugin..."
257
+ end
258
+ # The retry_after block expects to return a delay to wait before
259
+ # retrying the request
260
+ # nil means no waiting delay
261
+ nil
262
+ end
263
+ )
248
264
  .plugin(:stream)
249
265
  # See https://www.rubydoc.info/gems/httpx/1.3.3/HTTPX%2FOptions:initialize for the available options
250
266
  .with(
@@ -10,6 +10,7 @@ module ReactOnRailsPro
10
10
  # @param position [Symbol] The position of the chunk in the stream (:first, :middle, or :last)
11
11
  # The position parameter is used by actions that add content to the beginning or end of the stream
12
12
  @actions = [] # List to store all actions
13
+ @rescue_blocks = []
13
14
  end
14
15
 
15
16
  # Add a prepend action
@@ -39,27 +40,45 @@ module ReactOnRailsPro
39
40
  self # Return self to allow chaining
40
41
  end
41
42
 
43
+ def rescue(&block)
44
+ @rescue_blocks << block
45
+ self # Return self to allow chaining
46
+ end
47
+
42
48
  def handle_chunk(chunk, position)
43
49
  @actions.reduce(chunk) do |acc, action|
44
50
  action.call(acc, position)
45
51
  end
46
52
  end
47
53
 
48
- def each_chunk
49
- return enum_for(:each_chunk) unless block_given?
54
+ def each_chunk(&block) # rubocop:disable Metrics/CyclomaticComplexity
55
+ return enum_for(:each_chunk) unless block
50
56
 
51
57
  first_chunk = true
52
58
  @component.each_chunk do |chunk|
53
59
  position = first_chunk ? :first : :middle
54
60
  modified_chunk = handle_chunk(chunk, position)
55
- yield modified_chunk
61
+ yield(modified_chunk)
56
62
  first_chunk = false
57
63
  end
58
64
 
59
65
  # The last chunk contains the append content after the transformation
60
66
  # All transformations are applied to the append content
61
67
  last_chunk = handle_chunk("", :last)
62
- yield last_chunk unless last_chunk.empty?
68
+ yield(last_chunk) unless last_chunk.empty?
69
+ rescue StandardError => e
70
+ current_error = e
71
+ rescue_block_index = 0
72
+ while current_error.present? && (rescue_block_index < @rescue_blocks.size)
73
+ begin
74
+ @rescue_blocks[rescue_block_index].call(current_error, &block)
75
+ current_error = nil
76
+ rescue StandardError => inner_error
77
+ current_error = inner_error
78
+ end
79
+ rescue_block_index += 1
80
+ end
81
+ raise current_error if current_error.present?
63
82
  end
64
83
  end
65
84
 
@@ -75,9 +94,6 @@ module ReactOnRailsPro
75
94
 
76
95
  send_bundle = false
77
96
  error_body = +""
78
- # Retry logic for streaming requests is handled here by starting fresh requests.
79
- # The HTTPx connection used for streaming has retries disabled (see Request#connection_without_retries)
80
- # to prevent body duplication when partial chunks are already sent to the client.
81
97
  loop do
82
98
  stream_response = @request_executor.call(send_bundle)
83
99
 
@@ -89,6 +105,9 @@ module ReactOnRailsPro
89
105
  break
90
106
  rescue HTTPX::HTTPError => e
91
107
  send_bundle = handle_http_error(e, error_body, send_bundle)
108
+ rescue HTTPX::ReadTimeoutError => e
109
+ raise ReactOnRailsPro::Error, "Time out error while server side render streaming a component.\n" \
110
+ "Original error:\n#{e}\n#{e.backtrace}"
92
111
  end
93
112
  end
94
113
 
@@ -135,6 +154,7 @@ module ReactOnRailsPro
135
154
  line = "".b
136
155
 
137
156
  response.each do |chunk|
157
+ response.instance_variable_set(:@react_on_rails_received_first_chunk, true)
138
158
  line << chunk
139
159
 
140
160
  while (idx = line.index("\n"))
@@ -108,7 +108,7 @@ module ReactOnRailsPro
108
108
  @rsc_bundle_hash = calc_bundle_hash(server_rsc_bundle_js_file_path)
109
109
  end
110
110
 
111
- # Returns the hashed file name when using webpacker. Useful for creating cache keys.
111
+ # Returns the hashed file name when using Shakapacker. Useful for creating cache keys.
112
112
  def self.bundle_file_name(bundle_name)
113
113
  # bundle_js_uri_from_packer can return a file path or a HTTP URL (for files served from the dev server)
114
114
  # Pathname can handle both cases
@@ -117,8 +117,8 @@ module ReactOnRailsPro
117
117
  pathname.basename.to_s
118
118
  end
119
119
 
120
- # Returns the hashed file name of the server bundle when using webpacker.
121
- # Necessary fragment-caching keys.
120
+ # Returns the hashed file name of the server bundle when using Shakapacker.
121
+ # Necessary for fragment-caching keys.
122
122
  def self.server_bundle_file_name
123
123
  return @server_bundle_hash if @server_bundle_hash && !Rails.env.development?
124
124
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRailsPro
4
- VERSION = "16.2.0.beta.4"
4
+ VERSION = "16.2.0.beta.8"
5
5
  PROTOCOL_VERSION = "2.0.0"
6
6
  end
@@ -47,7 +47,7 @@ scripts:
47
47
  [ -f packages/node-renderer/dist/ReactOnRailsProNodeRenderer.js ] ||
48
48
  (nps build >/dev/null 2>&1 || true) &&
49
49
  [ -f packages/node-renderer/dist/ReactOnRailsProNodeRenderer.js ] ||
50
- { echo 'Building @shakacode-tools/react-on-rails-pro-node-renderer seems to have failed!'; }
50
+ { echo 'Building react-on-rails-pro-node-renderer seems to have failed!'; }
51
51
 
52
52
  clean:
53
53
  description: Clean the project
@@ -1,6 +1,6 @@
1
1
  {
2
- "name": "@shakacode-tools/react-on-rails-pro-node-renderer",
3
- "version": "16.2.0-beta.4",
2
+ "name": "react-on-rails-pro-node-renderer",
3
+ "version": "16.2.0-beta.8",
4
4
  "protocolVersion": "2.0.0",
5
5
  "description": "react-on-rails-pro JavaScript for react_on_rails_pro Ruby gem",
6
6
  "exports": {
@@ -17,9 +17,6 @@
17
17
  "bin": {
18
18
  "react-on-rails-pro-node-renderer": "packages/node-renderer/dist/default-node-renderer.js"
19
19
  },
20
- "publishConfig": {
21
- "registry": "https://npm.pkg.github.com"
22
- },
23
20
  "directories": {
24
21
  "doc": "docs"
25
22
  },
@@ -119,7 +116,7 @@
119
116
  },
120
117
  "repository": {
121
118
  "type": "git",
122
- "url": "git+https://github.com/shakacode-tools/react_on_rails_pro.git"
119
+ "url": "git+https://github.com/shakacode/react_on_rails.git"
123
120
  },
124
121
  "keywords": [
125
122
  "react",
@@ -132,9 +129,9 @@
132
129
  "author": "justin@shakacode.com",
133
130
  "license": "UNLICENSED",
134
131
  "bugs": {
135
- "url": "https://github.com/shakacode/react_on_rails_pro/issues"
132
+ "url": "https://github.com/shakacode/react_on_rails/issues"
136
133
  },
137
- "homepage": "https://github.com/shakacode/react_on_rails_pro#readme",
134
+ "homepage": "https://github.com/shakacode/react_on_rails/tree/master/react_on_rails_pro#readme",
138
135
  "jest": {
139
136
  "clearMocks": true,
140
137
  "collectCoverageFrom": [
@@ -4,7 +4,7 @@
4
4
  * @example
5
5
  * ```ts
6
6
  * import Bugsnag from '@bugsnag/js';
7
- * import { addNotifier, setupTracing } from '@shakacode-tools/react-on-rails-pro-node-renderer/integrations/api';
7
+ * import { addNotifier, setupTracing } from 'react-on-rails-pro-node-renderer/integrations/api';
8
8
  * Bugsnag.start({ ... });
9
9
  *
10
10
  * addNotifier((msg) => { Bugsnag.notify(msg); });
@@ -13,9 +13,9 @@ require "uri"
13
13
  # rake react_on_rails_pro:verify_public_key # Verify current configuration
14
14
  # rake react_on_rails_pro:public_key_help # Show help
15
15
 
16
- namespace :react_on_rails_pro do
16
+ namespace :react_on_rails_pro do # rubocop:disable Metrics/BlockLength
17
17
  desc "Update the public key for React on Rails Pro license validation"
18
- task :update_public_key, [:source] do |_task, args|
18
+ task :update_public_key, [:source] do |_task, args| # rubocop:disable Metrics/BlockLength
19
19
  source = args[:source] || "production"
20
20
 
21
21
  # Determine the API URL based on the source
@@ -68,7 +68,7 @@ namespace :react_on_rails_pro do
68
68
  # ShakaCode's public key for React on Rails Pro license verification
69
69
  # The private key corresponding to this public key is held by ShakaCode
70
70
  # and is never committed to the repository
71
- # Last updated: #{Time.now.utc.strftime("%Y-%m-%d %H:%M:%S UTC")}
71
+ # Last updated: #{Time.now.utc.strftime('%Y-%m-%d %H:%M:%S UTC')}
72
72
  # Source: #{api_url}
73
73
  #
74
74
  # You can update this public key by running the rake task:
@@ -86,12 +86,13 @@ namespace :react_on_rails_pro do
86
86
  puts "✅ Updated Ruby public key: #{ruby_file_path}"
87
87
 
88
88
  # Update Node/TypeScript public key file
89
- node_file_path = File.join(File.dirname(__FILE__), "..", "packages", "node-renderer", "src", "shared", "licensePublicKey.ts")
89
+ node_file_path = File.join(File.dirname(__FILE__), "..", "packages", "node-renderer", "src", "shared",
90
+ "licensePublicKey.ts")
90
91
  node_content = <<~TYPESCRIPT
91
92
  // ShakaCode's public key for React on Rails Pro license verification
92
93
  // The private key corresponding to this public key is held by ShakaCode
93
94
  // and is never committed to the repository
94
- // Last updated: #{Time.now.utc.strftime("%Y-%m-%d %H:%M:%S UTC")}
95
+ // Last updated: #{Time.now.utc.strftime('%Y-%m-%d %H:%M:%S UTC')}
95
96
  // Source: #{api_url}
96
97
  //
97
98
  // You can update this public key by running the rake task:
@@ -37,6 +37,7 @@ Gem::Specification.new do |s|
37
37
  s.add_runtime_dependency "execjs", "~> 2.9"
38
38
  s.add_runtime_dependency "httpx", "~> 1.5"
39
39
  s.add_runtime_dependency "jwt", "~> 2.7"
40
+ s.add_runtime_dependency "async", ">= 2.6"
40
41
  s.add_runtime_dependency "rainbow"
41
42
  s.add_runtime_dependency "react_on_rails", ReactOnRails::VERSION
42
43
  s.add_development_dependency "bundler"
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: ../../..
11
11
  specs:
12
- react_on_rails (16.2.0.beta.4)
12
+ react_on_rails (16.2.0.beta.8)
13
13
  addressable
14
14
  connection_pool
15
15
  execjs (~> 2.5)
@@ -20,14 +20,15 @@ PATH
20
20
  PATH
21
21
  remote: ../..
22
22
  specs:
23
- react_on_rails_pro (16.2.0.beta.4)
23
+ react_on_rails_pro (16.2.0.beta.8)
24
24
  addressable
25
+ async (>= 2.6)
25
26
  connection_pool
26
27
  execjs (~> 2.9)
27
28
  httpx (~> 1.5)
28
29
  jwt (~> 2.7)
29
30
  rainbow
30
- react_on_rails (= 16.2.0.beta.4)
31
+ react_on_rails (= 16.2.0.beta.8)
31
32
 
32
33
  GEM
33
34
  remote: https://rubygems.org/
@@ -107,6 +108,12 @@ GEM
107
108
  public_suffix (>= 2.0.2, < 7.0)
108
109
  amazing_print (1.6.0)
109
110
  ast (2.4.2)
111
+ async (2.34.0)
112
+ console (~> 1.29)
113
+ fiber-annotation
114
+ io-event (~> 1.11)
115
+ metrics (~> 0.12)
116
+ traces (~> 0.18)
110
117
  base64 (0.2.0)
111
118
  benchmark (0.4.0)
112
119
  bigdecimal (3.1.9)
@@ -131,6 +138,10 @@ GEM
131
138
  coderay (1.1.3)
132
139
  concurrent-ruby (1.3.5)
133
140
  connection_pool (2.5.0)
141
+ console (1.34.2)
142
+ fiber-annotation
143
+ fiber-local (~> 1.1)
144
+ json
134
145
  coveralls (0.8.23)
135
146
  json (>= 1.8, < 3)
136
147
  simplecov (~> 0.16.1)
@@ -165,6 +176,9 @@ GEM
165
176
  ffi (1.17.0-x86_64-darwin)
166
177
  ffi (1.17.0-x86_64-linux-gnu)
167
178
  ffi (1.17.0-x86_64-linux-musl)
179
+ fiber-annotation (0.2.0)
180
+ fiber-local (1.1.0)
181
+ fiber-storage
168
182
  fiber-storage (1.0.0)
169
183
  generator_spec (0.10.0)
170
184
  activesupport (>= 3.0.0)
@@ -184,6 +198,7 @@ GEM
184
198
  i18n (1.14.7)
185
199
  concurrent-ruby (~> 1.0)
186
200
  io-console (0.8.0)
201
+ io-event (1.14.2)
187
202
  irb (1.15.1)
188
203
  pp (>= 0.6.0)
189
204
  rdoc (>= 4.0.0)
@@ -216,6 +231,7 @@ GEM
216
231
  marcel (1.0.4)
217
232
  matrix (0.4.2)
218
233
  method_source (1.1.0)
234
+ metrics (0.15.0)
219
235
  mini_mime (1.1.5)
220
236
  mini_portile2 (2.8.8)
221
237
  minitest (5.25.4)
@@ -447,6 +463,7 @@ GEM
447
463
  tins (1.33.0)
448
464
  bigdecimal
449
465
  sync
466
+ traces (0.18.2)
450
467
  turbolinks (5.2.1)
451
468
  turbolinks-source (~> 5.2)
452
469
  turbolinks-source (5.2.0)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class PagesController < ApplicationController
3
+ class PagesController < ApplicationController # rubocop:disable Metrics/ClassLength
4
4
  include ReactOnRailsPro::RSCPayloadRenderer
5
5
  include RscPostsPageOverRedisHelper
6
6
 
@@ -85,8 +85,8 @@ class PagesController < ApplicationController
85
85
  ensure
86
86
  begin
87
87
  redis&.close
88
- rescue StandardError => close_err
89
- Rails.logger.warn "Failed to close Redis: #{close_err.message}"
88
+ rescue StandardError => e
89
+ Rails.logger.warn "Failed to close Redis: #{e.message}"
90
90
  end
91
91
  end
92
92
 
@@ -1,9 +1,5 @@
1
- #!/usr/bin/env bash
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- if ! command -v foreman &> /dev/null
4
- then
5
- echo "Installing foreman..."
6
- gem install foreman
7
- fi
8
-
9
- foreman start -f Procfile.dev
4
+ # This script calls the base dev script with a fixed route for the dummy app
5
+ exec File.join(__dir__, "../../../../lib/generators/react_on_rails/templates/base/base/bin/dev"), "--route=/", *ARGV
@@ -5,14 +5,14 @@ const Sentry = require('@sentry/node');
5
5
  const { env } = process;
6
6
 
7
7
  // Use this for package installation test:
8
- const { reactOnRailsProNodeRenderer } = require('@shakacode-tools/react-on-rails-pro-node-renderer');
8
+ const { reactOnRailsProNodeRenderer } = require('react-on-rails-pro-node-renderer');
9
9
 
10
10
  Honeybadger.configure({
11
11
  // This is a test account for React on Rails Pro. Substitute your own.
12
12
  apiKey: 'a602365c',
13
13
  environment: process.env.NODE_ENV ?? 'development',
14
14
  });
15
- require('@shakacode-tools/react-on-rails-pro-node-renderer/integrations/honeybadger').init();
15
+ require('react-on-rails-pro-node-renderer/integrations/honeybadger').init();
16
16
 
17
17
  // This is a test account for React on Rails Pro.
18
18
  // Substitute your own DSN.
@@ -25,7 +25,7 @@ Sentry.init({
25
25
  // Sentry recommends adjusting this value in production, or using tracesSampler for finer control
26
26
  tracesSampleRate: 1.0,
27
27
  });
28
- require('@shakacode-tools/react-on-rails-pro-node-renderer/integrations/sentry').init({ tracing: true });
28
+ require('react-on-rails-pro-node-renderer/integrations/sentry').init({ tracing: true });
29
29
 
30
30
  const config = {
31
31
  // This is the default but avoids searching for the Rails root
@@ -69,7 +69,7 @@ Rails.application.configure do
69
69
  config.active_support.deprecation = :notify
70
70
 
71
71
  # Use default logging formatter so that PID and timestamp are not suppressed.
72
- config.log_formatter = ::Logger::Formatter.new
72
+ config.log_formatter = Logger::Formatter.new
73
73
 
74
74
  # Use a different logger for distributed setups.
75
75
  # require 'syslog/logger'