react_on_rails 14.0.4 → 15.0.0.alpha.1

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: 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