react_on_rails 14.0.4 → 15.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 990382215a33db46c9f5b8bdf0e5db38fba4e6233da6ff1a5f3840428ac9e092
4
- data.tar.gz: 21e052cfea0a8121d8c6ebd4fd3f4688ced23ef7b0b40df653889f6388f95834
3
+ metadata.gz: 7d60051000fbd817b3499b1de6f13c9abeaf5627bee250c50bf0d748ce3532a5
4
+ data.tar.gz: 4eccfe81e12b647503fa6e690c514d4d14d6704ab1e5c7f64282cafa7709d6e2
5
5
  SHA512:
6
- metadata.gz: 4c37af672c59bf60b452af1684a25fdc75caf8a48a115a84179816a16a9933120628b4e516dd593f60550d6ecd3df8a4ee8e5ba4a670c2bd5cc9d43dfeea870b
7
- data.tar.gz: ddda7ad407c195b32d15fcbad434e34b9fa0e5003666ddded2953c369a0081f1f14a9fd3b03bf8ba5678b97ac09402a1fdfe123815a0c4a895caabeb518c548b
6
+ metadata.gz: 99004f6792fe209d21474c7b5b311ac8a02cce27740b69164e44079983a5852895aa99ed12530043ba64ad6920d189cb6b19ce3957aca83b6bab06f75bf702ee
7
+ data.tar.gz: 2be5eb3178a913c90c7b4e640812bccc479245d0052d95751317f543c80e7bf9429f9fd61cbc1c5edb917aafbead33502c75fb63fd8ab183480aaa44124f3dc5
data/CHANGELOG.md CHANGED
@@ -18,6 +18,26 @@ Please follow the recommendations outlined at [keepachangelog.com](http://keepac
18
18
  ### [Unreleased]
19
19
  Changes since the last non-beta release.
20
20
 
21
+ #### Added(https://github.com/AbanoubGhadban).
22
+ - Added streaming server rendering support:
23
+ - [PR #1633](https://github.com/shakacode/react_on_rails/pull/1633) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
24
+ - New `stream_react_component` helper for adding streamed components to views
25
+ - New `streamServerRenderedReactComponent` function in the react-on-rails package that uses React 18's `renderToPipeableStream` API
26
+ - Enables progressive page loading and improved performance for server-rendered React components
27
+ - Added support for replaying console logs that occur during server rendering of streamed React components. This enables debugging of server-side rendering issues by capturing and displaying console output on the client and on the server output. [PR #1647](https://github.com/shakacode/react_on_rails/pull/1647) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
28
+ - Added support for handling errors happening during server rendering of streamed React components. It handles errors that happen during the initial render and errors that happen inside suspense boundaries. [PR #1648](https://github.com/shakacode/react_on_rails/pull/1648) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
29
+
30
+ #### Changed
31
+ - Console replay script generation now awaits the render request promise before generating, allowing it to capture console logs from asynchronous operations. This requires using a version of the Node renderer that supports replaying async console logs. [PR #1649](https://github.com/shakacode/react_on_rails/pull/1649) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
32
+
33
+ #### Fixed
34
+ - Incorrect type and confusing name for `ReactOnRails.registerStore`, use `registerStoreGenerators` instead. [PR 1651](https://github.com/shakacode/react_on_rails/pull/1651) by [alexeyr-ci](https://github.com/alexeyr-ci).
35
+
36
+ ### [14.0.5] - 2024-08-20
37
+ #### Fixed
38
+ - Should force load react-components which send over turbo-stream [PR #1620](https://github.com/shakacode/react_on_rails/pull/1620) by [theforestvn88](https://github.com/theforestvn88).
39
+
40
+ ### [14.0.4] - 2024-07-02
21
41
 
22
42
  #### Improved
23
43
  - Improved dependency management by integrating package_json. [PR 1639](https://github.com/shakacode/react_on_rails/pull/1639) by [vaukalak](https://github.com/vaukalak).
@@ -25,7 +45,6 @@ Changes since the last non-beta release.
25
45
  #### Changed
26
46
  - Update outdated GitHub Actions to use Node.js 20.0 versions instead [PR 1623](https://github.com/shakacode/react_on_rails/pull/1623) by [adriangohjw](https://github.com/adriangohjw).
27
47
 
28
-
29
48
  ### [14.0.3] - 2024-06-28
30
49
 
31
50
  #### Fixed
@@ -1148,7 +1167,9 @@ Best done with Object destructing:
1148
1167
  ##### Fixed
1149
1168
  - Fix several generator-related issues.
1150
1169
 
1151
- [Unreleased]: https://github.com/shakacode/react_on_rails/compare/14.0.3...master
1170
+ [Unreleased]: https://github.com/shakacode/react_on_rails/compare/14.0.5...master
1171
+ [14.0.5]: https://github.com/shakacode/react_on_rails/compare/14.0.4...14.0.5
1172
+ [14.0.4]: https://github.com/shakacode/react_on_rails/compare/14.0.3...14.0.4
1152
1173
  [14.0.3]: https://github.com/shakacode/react_on_rails/compare/14.0.2...14.0.3
1153
1174
  [14.0.2]: https://github.com/shakacode/react_on_rails/compare/14.0.1...14.0.2
1154
1175
  [14.0.1]: https://github.com/shakacode/react_on_rails/compare/14.0.0...14.0.1
@@ -22,6 +22,8 @@ gem "sprockets", "~> 4.0"
22
22
 
23
23
  gem "amazing_print"
24
24
 
25
+ gem "turbo-rails"
26
+
25
27
  group :development, :test do
26
28
  gem "package_json"
27
29
  gem "listen"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- react_on_rails (14.0.3)
4
+ react_on_rails (14.0.5)
5
5
  addressable
6
6
  connection_pool
7
7
  execjs (~> 2.5)
@@ -369,6 +369,10 @@ GEM
369
369
  tins (1.33.0)
370
370
  bigdecimal
371
371
  sync
372
+ turbo-rails (2.0.6)
373
+ actionpack (>= 6.0.0)
374
+ activejob (>= 6.0.0)
375
+ railties (>= 6.0.0)
372
376
  turbolinks (5.2.1)
373
377
  turbolinks-source (~> 5.2)
374
378
  turbolinks-source (5.2.0)
@@ -431,6 +435,7 @@ DEPENDENCIES
431
435
  spring (~> 4.0)
432
436
  sprockets (~> 4.0)
433
437
  sqlite3 (~> 1.6)
438
+ turbo-rails
434
439
  turbolinks
435
440
  uglifier
436
441
  webdrivers (= 5.3.0)
data/README.md CHANGED
@@ -17,6 +17,7 @@
17
17
  [![Linting](https://github.com/shakacode/react_on_rails/actions/workflows/lint-js-and-ruby.yml/badge.svg)](https://github.com/shakacode/react_on_rails/actions/workflows/lint-js-and-ruby.yml)
18
18
 
19
19
  # News
20
+ * [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) supports the latest features of React 18, including [React Server Components](https://react.dev/reference/rsc/server-components) and [streaming](https://react.dev/reference/react-dom/server/renderToPipeableStream). Contact [Justin Gordon](mailto:justin@shakacode.com) for more information.
20
21
  * ShakaCode now maintains the official successor to `rails/webpacker`, [`shakapacker`](https://github.com/shakacode/shakapacker).
21
22
  * Project is updated to support Rails 7 and Shakapacker v6+!
22
23
 
data/SUMMARY.md CHANGED
@@ -17,6 +17,7 @@ Here is the new link:
17
17
  + [How React on Rails Works](docs/outdated/how-react-on-rails-works.md)
18
18
  + [Client vs. Server Rendering](./docs/guides/client-vs-server-rendering.md)
19
19
  + [React Server Rendering](./docs/guides/react-server-rendering.md)
20
+ + [🚀 Next-Gen Server Rendering: Streaming with React 18's Latest APIs](./docs/guides/streaming-server-rendering.md)
20
21
  + [Render-Functions and the RailsContext](docs/guides/render-functions-and-railscontext.md)
21
22
  + [Caching and Performance: React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki).
22
23
  + [Deployment](docs/guides/deployment.md).
@@ -39,7 +39,9 @@ module ReactOnRails
39
39
  i18n_output_format: nil,
40
40
  components_subdirectory: nil,
41
41
  make_generated_server_bundle_the_entrypoint: false,
42
- defer_generated_component_packs: true
42
+ defer_generated_component_packs: true,
43
+ # forces the loading of React components
44
+ force_load: false
43
45
  )
44
46
  end
45
47
 
@@ -53,7 +55,8 @@ module ReactOnRails
53
55
  :server_render_method, :random_dom_id, :auto_load_bundle,
54
56
  :same_bundle_for_client_and_server, :rendering_props_extension,
55
57
  :make_generated_server_bundle_the_entrypoint,
56
- :defer_generated_component_packs
58
+ :defer_generated_component_packs,
59
+ :force_load
57
60
 
58
61
  # rubocop:disable Metrics/AbcSize
59
62
  def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
@@ -68,7 +71,7 @@ module ReactOnRails
68
71
  same_bundle_for_client_and_server: nil,
69
72
  i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil,
70
73
  random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil,
71
- components_subdirectory: nil, auto_load_bundle: nil)
74
+ components_subdirectory: nil, auto_load_bundle: nil, force_load: nil)
72
75
  self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
73
76
  self.generated_assets_dirs = generated_assets_dirs
74
77
  self.generated_assets_dir = generated_assets_dir
@@ -106,6 +109,7 @@ module ReactOnRails
106
109
  self.auto_load_bundle = auto_load_bundle
107
110
  self.make_generated_server_bundle_the_entrypoint = make_generated_server_bundle_the_entrypoint
108
111
  self.defer_generated_component_packs = defer_generated_component_packs
112
+ self.force_load = force_load
109
113
  end
110
114
  # rubocop:enable Metrics/AbcSize
111
115
 
@@ -91,6 +91,64 @@ module ReactOnRails
91
91
  end
92
92
  end
93
93
 
94
+ # Streams a server-side rendered React component using React's `renderToPipeableStream`.
95
+ # Supports React 18 features like Suspense, concurrent rendering, and selective hydration.
96
+ # Enables progressive rendering and improved performance for large components.
97
+ #
98
+ # Note: This function can only be used with React on Rails Pro.
99
+ # The view that uses this function must be rendered using the
100
+ # `stream_view_containing_react_components` method from the React on Rails Pro gem.
101
+ #
102
+ # Example of an async React component that can benefit from streaming:
103
+ #
104
+ # const AsyncComponent = async () => {
105
+ # const data = await fetchData();
106
+ # return <div>{data}</div>;
107
+ # };
108
+ #
109
+ # function App() {
110
+ # return (
111
+ # <Suspense fallback={<div>Loading...</div>}>
112
+ # <AsyncComponent />
113
+ # </Suspense>
114
+ # );
115
+ # }
116
+ #
117
+ # @param [String] component_name Name of your registered component
118
+ # @param [Hash] options Options for rendering
119
+ # @option options [Hash] :props Props to pass to the react component
120
+ # @option options [String] :dom_id DOM ID of the component container
121
+ # @option options [Hash] :html_options Options passed to content_tag
122
+ # @option options [Boolean] :prerender Set to false to disable server-side rendering
123
+ # @option options [Boolean] :trace Set to true to add extra debugging information to the HTML
124
+ # @option options [Boolean] :raise_on_prerender_error Set to true to raise exceptions during server-side rendering
125
+ # Any other options are passed to the content tag, including the id.
126
+ def stream_react_component(component_name, options = {})
127
+ unless ReactOnRails::Utils.react_on_rails_pro?
128
+ raise ReactOnRails::Error,
129
+ "You must use React on Rails Pro to use the stream_react_component method."
130
+ end
131
+
132
+ if @rorp_rendering_fibers.nil?
133
+ raise ReactOnRails::Error,
134
+ "You must call stream_view_containing_react_components to render the view containing the react component"
135
+ end
136
+
137
+ rendering_fiber = Fiber.new do
138
+ stream = internal_stream_react_component(component_name, options)
139
+ stream.each_chunk do |chunk|
140
+ Fiber.yield chunk
141
+ end
142
+ end
143
+
144
+ @rorp_rendering_fibers << rendering_fiber
145
+
146
+ # return the first chunk of the fiber
147
+ # It contains the initial html of the component
148
+ # all updates will be appended to the stream sent to browser
149
+ rendering_fiber.resume
150
+ end
151
+
94
152
  # react_component_hash is used to return multiple HTML strings for server rendering, such as for
95
153
  # adding meta-tags to a page.
96
154
  # It is exactly like react_component except for the following:
@@ -330,6 +388,16 @@ module ReactOnRails
330
388
 
331
389
  private
332
390
 
391
+ def internal_stream_react_component(component_name, options = {})
392
+ options = options.merge(stream?: true)
393
+ result = internal_react_component(component_name, options)
394
+ build_react_component_result_for_server_streamed_content(
395
+ rendered_html_stream: result[:result],
396
+ component_specification_tag: result[:tag],
397
+ render_options: result[:render_options]
398
+ )
399
+ end
400
+
333
401
  def generated_components_pack_path(component_name)
334
402
  "#{ReactOnRails::PackerUtils.packer_source_entry_path}/generated/#{component_name}.js"
335
403
  end
@@ -361,6 +429,32 @@ module ReactOnRails
361
429
  prepend_render_rails_context(result)
362
430
  end
363
431
 
432
+ def build_react_component_result_for_server_streamed_content(
433
+ rendered_html_stream:,
434
+ component_specification_tag:,
435
+ render_options:
436
+ )
437
+ is_first_chunk = true
438
+ rendered_html_stream.transform do |chunk_json_result|
439
+ if is_first_chunk
440
+ is_first_chunk = false
441
+ build_react_component_result_for_server_rendered_string(
442
+ server_rendered_html: chunk_json_result["html"],
443
+ component_specification_tag: component_specification_tag,
444
+ console_script: chunk_json_result["consoleReplayScript"],
445
+ render_options: render_options
446
+ )
447
+ else
448
+ result_console_script = render_options.replay_console ? chunk_json_result["consoleReplayScript"] : ""
449
+ # No need to prepend component_specification_tag or add rails context again
450
+ # as they're already included in the first chunk
451
+ compose_react_component_html_with_spec_and_console(
452
+ "", chunk_json_result["html"], result_console_script
453
+ )
454
+ end
455
+ end
456
+ end
457
+
364
458
  def build_react_component_result_for_server_rendered_hash(
365
459
  server_rendered_html: required("server_rendered_html"),
366
460
  component_specification_tag: required("component_specification_tag"),
@@ -397,27 +491,30 @@ module ReactOnRails
397
491
 
398
492
  def compose_react_component_html_with_spec_and_console(component_specification_tag, rendered_output, console_script)
399
493
  # IMPORTANT: Ensure that we mark string as html_safe to avoid escaping.
400
- <<~HTML.html_safe
494
+ html_content = <<~HTML
401
495
  #{rendered_output}
402
496
  #{component_specification_tag}
403
497
  #{console_script}
404
498
  HTML
499
+ html_content.strip.html_safe
405
500
  end
406
501
 
407
- # prepend the rails_context if not yet applied
408
- def prepend_render_rails_context(render_value)
409
- return render_value if @rendered_rails_context
502
+ def rails_context_if_not_already_rendered
503
+ return "" if @rendered_rails_context
410
504
 
411
505
  data = rails_context(server_side: false)
412
506
 
413
507
  @rendered_rails_context = true
414
508
 
415
- rails_context_content = content_tag(:script,
416
- json_safe_and_pretty(data).html_safe,
417
- type: "application/json",
418
- id: "js-react-on-rails-context")
509
+ content_tag(:script,
510
+ json_safe_and_pretty(data).html_safe,
511
+ type: "application/json",
512
+ id: "js-react-on-rails-context")
513
+ end
419
514
 
420
- "#{rails_context_content}\n#{render_value}".html_safe
515
+ # prepend the rails_context if not yet applied
516
+ def prepend_render_rails_context(render_value)
517
+ "#{rails_context_if_not_already_rendered}\n#{render_value}".strip.html_safe
421
518
  end
422
519
 
423
520
  def internal_react_component(react_component_name, options = {})
@@ -441,6 +538,14 @@ module ReactOnRails
441
538
  "data-trace" => (render_options.trace ? true : nil),
442
539
  "data-dom-id" => render_options.dom_id)
443
540
 
541
+ if render_options.force_load
542
+ component_specification_tag.concat(
543
+ content_tag(:script, %(
544
+ ReactOnRails.reactOnRailsComponentLoaded('#{render_options.dom_id}');
545
+ ).html_safe)
546
+ )
547
+ end
548
+
444
549
  load_pack_for_generated_component(react_component_name, render_options)
445
550
  # Create the HTML rendering part
446
551
  result = server_rendered_react_component(render_options)
@@ -465,6 +570,25 @@ module ReactOnRails
465
570
  props.is_a?(String) ? props : props.to_json
466
571
  end
467
572
 
573
+ def raise_prerender_error(json_result, react_component_name, props, js_code)
574
+ raise ReactOnRails::PrerenderError.new(
575
+ component_name: react_component_name,
576
+ props: sanitized_props_string(props),
577
+ err: nil,
578
+ js_code: js_code,
579
+ console_messages: json_result["consoleReplayScript"]
580
+ )
581
+ end
582
+
583
+ def should_raise_streaming_prerender_error?(chunk_json_result, render_options)
584
+ chunk_json_result["hasErrors"] &&
585
+ (if chunk_json_result["isShellReady"]
586
+ render_options.raise_non_shell_server_rendering_errors
587
+ else
588
+ render_options.raise_on_prerender_error
589
+ end)
590
+ end
591
+
468
592
  # Returns object with values that are NOT html_safe!
469
593
  def server_rendered_react_component(render_options)
470
594
  return { "html" => "", "consoleReplayScript" => "" } unless render_options.prerender
@@ -512,16 +636,18 @@ module ReactOnRails
512
636
  js_code: js_code)
513
637
  end
514
638
 
515
- if result["hasErrors"] && render_options.raise_on_prerender_error
516
- # We caught this exception on our backtrace handler
517
- raise ReactOnRails::PrerenderError.new(component_name: react_component_name,
518
- # Sanitize as this might be browser logged
519
- props: sanitized_props_string(props),
520
- err: nil,
521
- js_code: js_code,
522
- console_messages: result["consoleReplayScript"])
523
-
639
+ if render_options.stream?
640
+ result.transform do |chunk_json_result|
641
+ if should_raise_streaming_prerender_error?(chunk_json_result, render_options)
642
+ raise_prerender_error(chunk_json_result, react_component_name, props, js_code)
643
+ end
644
+ # It doesn't make any transformation, it listens and raises error if a chunk has errors
645
+ chunk_json_result
646
+ end
647
+ elsif result["hasErrors"] && render_options.raise_on_prerender_error
648
+ raise_prerender_error(result, react_component_name, props, js_code)
524
649
  end
650
+
525
651
  result
526
652
  end
527
653
 
@@ -87,10 +87,18 @@ module ReactOnRails
87
87
  retrieve_configuration_value_for(:raise_on_prerender_error)
88
88
  end
89
89
 
90
+ def raise_non_shell_server_rendering_errors
91
+ retrieve_react_on_rails_pro_config_value_for(:raise_non_shell_server_rendering_errors)
92
+ end
93
+
90
94
  def logging_on_server
91
95
  retrieve_configuration_value_for(:logging_on_server)
92
96
  end
93
97
 
98
+ def force_load
99
+ retrieve_configuration_value_for(:force_load)
100
+ end
101
+
94
102
  def to_s
95
103
  "{ react_component_name = #{react_component_name}, options = #{options}, request_digest = #{request_digest}"
96
104
  end
@@ -103,6 +111,10 @@ module ReactOnRails
103
111
  options[key] = value
104
112
  end
105
113
 
114
+ def stream?
115
+ options[:stream?]
116
+ end
117
+
106
118
  private
107
119
 
108
120
  attr_reader :options
@@ -120,6 +132,14 @@ module ReactOnRails
120
132
  ReactOnRails.configuration.public_send(key)
121
133
  end
122
134
  end
135
+
136
+ def retrieve_react_on_rails_pro_config_value_for(key)
137
+ options.fetch(key) do
138
+ return nil unless ReactOnRails::Utils.react_on_rails_pro?
139
+
140
+ ReactOnRailsPro.configuration.public_send(key)
141
+ end
142
+ end
123
143
  end
124
144
  end
125
145
  end
@@ -46,7 +46,7 @@ module ReactOnRails
46
46
  # Note, js_code does not have to be based on React.
47
47
  # js_code MUST RETURN json stringify Object
48
48
  # Calling code will probably call 'html_safe' on return value before rendering to the view.
49
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
49
+ # rubocop:disable Metrics/CyclomaticComplexity
50
50
  def exec_server_render_js(js_code, render_options, js_evaluator = nil)
51
51
  js_evaluator ||= self
52
52
  if render_options.trace
@@ -56,7 +56,11 @@ module ReactOnRails
56
56
  @file_index += 1
57
57
  end
58
58
  begin
59
- json_string = js_evaluator.eval_js(js_code, render_options)
59
+ result = if render_options.stream?
60
+ js_evaluator.eval_streaming_js(js_code, render_options)
61
+ else
62
+ js_evaluator.eval_js(js_code, render_options)
63
+ end
60
64
  rescue StandardError => err
61
65
  msg = <<~MSG
62
66
  Error evaluating server bundle. Check your webpack configuration.
@@ -71,26 +75,14 @@ module ReactOnRails
71
75
  end
72
76
  raise ReactOnRails::Error, msg, err.backtrace
73
77
  end
74
- result = nil
75
- begin
76
- result = JSON.parse(json_string)
77
- rescue JSON::ParserError => e
78
- raise ReactOnRails::JsonParseError.new(parse_error: e, json: json_string)
79
- end
80
78
 
81
- if render_options.logging_on_server
82
- console_script = result["consoleReplayScript"]
83
- console_script_lines = console_script.split("\n")
84
- console_script_lines = console_script_lines[2..-2]
85
- re = /console\.(?:log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
86
- console_script_lines&.each do |line|
87
- match = re.match(line)
88
- Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
89
- end
90
- end
91
- result
79
+ return parse_result_and_replay_console_messages(result, render_options) unless render_options.stream?
80
+
81
+ # Streamed component is returned as stream of strings.
82
+ # We need to parse each chunk and replay the console messages.
83
+ result.transform { |chunk| parse_result_and_replay_console_messages(chunk, render_options) }
92
84
  end
93
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
85
+ # rubocop:enable Metrics/CyclomaticComplexity
94
86
 
95
87
  def trace_js_code_used(msg, js_code, file_name = "tmp/server-generated.js", force: false)
96
88
  return unless ReactOnRails.configuration.trace || force
@@ -233,6 +225,28 @@ module ReactOnRails
233
225
  msg = "file_url_to_string #{url} failed\nError is: #{e}"
234
226
  raise ReactOnRails::Error, msg
235
227
  end
228
+
229
+ def parse_result_and_replay_console_messages(result_string, render_options)
230
+ result = nil
231
+ begin
232
+ result = JSON.parse(result_string)
233
+ rescue JSON::ParserError => e
234
+ raise ReactOnRails::JsonParseError.new(parse_error: e, json: result_string)
235
+ end
236
+
237
+ if render_options.logging_on_server
238
+ console_script = result["consoleReplayScript"]
239
+ console_script_lines = console_script.split("\n")
240
+ # Regular expression to match console.log or console.error calls with SERVER prefix
241
+ re = /console\.(?:log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
242
+ console_script_lines&.each do |line|
243
+ match = re.match(line)
244
+ # Log matched messages to Rails logger with react_on_rails prefix
245
+ Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
246
+ end
247
+ end
248
+ result
249
+ end
236
250
  end
237
251
  # rubocop:enable Metrics/ClassLength
238
252
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRails
4
- VERSION = "14.0.4"
4
+ VERSION = "15.0.0.alpha.1"
5
5
  end
data/tsconfig.json CHANGED
@@ -8,6 +8,7 @@
8
8
  "noImplicitAny": true,
9
9
  "outDir": "node_package/lib",
10
10
  "strict": true,
11
+ "incremental": true,
11
12
  "target": "es5"
12
13
  },
13
14
  "include": ["node_package/src/**/*"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react_on_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 14.0.4
4
+ version: 15.0.0.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-03 00:00:00.000000000 Z
11
+ date: 2024-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable