Module: ReactOnRailsPro::Stream

Extended by:
ActiveSupport::Concern
Defined in:
lib/react_on_rails_pro/concerns/stream.rb

Overview

rubocop:disable Metrics/ModuleLength

Defined Under Namespace

Classes: RendererServerTimingAttemptCollector

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.record_renderer_response_headers(headers) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 77

def record_renderer_response_headers(headers)
  collector = renderer_server_timing_collector
  return unless collector

  server_timing_values(headers).each do |value|
    entry = sanitize_server_timing_header_entry(value)
    next if entry.blank?

    collector << entry
    renderer_server_timing_attempt_collector&.append(entry, collector:)
  end
end

.renderer_server_timing_collectorObject



90
91
92
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 90

def renderer_server_timing_collector
  Thread.current[RENDERER_SERVER_TIMING_COLLECTOR_KEY]
end

.renderer_server_timing_collector=(collector) ⇒ Object



94
95
96
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 94

def renderer_server_timing_collector=(collector)
  Thread.current[RENDERER_SERVER_TIMING_COLLECTOR_KEY] = collector
end

.renderer_server_timing_collector_snapshotObject



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 106

def renderer_server_timing_collector_snapshot
  collector = renderer_server_timing_collector
  return unless collector

  attempt_collector = RendererServerTimingAttemptCollector.new(
    collector:,
    previous_attempt_collector: renderer_server_timing_attempt_collector
  )
  self.renderer_server_timing_attempt_collector = attempt_collector

  attempt_collector
end

.restore_renderer_server_timing_collector_snapshot(attempt_collector) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 119

def restore_renderer_server_timing_collector_snapshot(attempt_collector)
  return unless attempt_collector

  collector = renderer_server_timing_collector
  return unless collector.equal?(attempt_collector.collector)

  attempt_collector.remove_appended_entries
ensure
  if attempt_collector && renderer_server_timing_attempt_collector.equal?(attempt_collector)
    self.renderer_server_timing_attempt_collector = attempt_collector.previous_attempt_collector
  end
end

.with_renderer_server_timing_collector(collector) ⇒ Object



98
99
100
101
102
103
104
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 98

def with_renderer_server_timing_collector(collector)
  previous_collector = renderer_server_timing_collector
  self.renderer_server_timing_collector = collector
  yield
ensure
  self.renderer_server_timing_collector = previous_collector
end

Instance Method Details

#stream_view_containing_react_components(template:, close_stream_at_end: true, content_type: nil, rsc_stream_observability: false, **render_options) ⇒ Object

Note:

The stream_react_component helper is defined in the react_on_rails gem. For more details, refer to lib/react_on_rails/helper.rb in the react_on_rails repository.

Streams React components within a specified template to the client.

components must be added to the view using the stream_react_component helper.

Examples:

stream_view_containing_react_components(template: 'path/to/your/template')
stream_view_containing_react_components(
  template: 'path/to/your/template',
  close_stream_at_end: false,
  layout: false
)

Parameters:

  • template (String)

    The path to the template file to be streamed.

  • close_stream_at_end (Boolean) (defaults to: true)

    Whether to automatically close the stream after rendering (default: true).

  • content_type (String, nil) (defaults to: nil)

    Optional response content type. Set after rendering but before the first stream write, overriding any content type inferred from the template format. When using a non-HTML formats: value (for example [:text]), pass content_type too unless committing the format-derived MIME type is intentional.

  • rsc_stream_observability (Boolean) (defaults to: false)

    Whether to emit browser-observable streamed RSC timing marks.

  • render_options (Hash)

    Additional options to pass to render_to_string.

See Also:

  • ReactOnRails::Helper#stream_react_component


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 217

def stream_view_containing_react_components(
  template:, close_stream_at_end: true, content_type: nil, rsc_stream_observability: false, **render_options
)
  previous_rsc_stream_observability_state = current_rsc_stream_observability_state
  require_streaming_dependencies
  warn_on_non_html_formats_without_content_type(render_options[:formats], content_type)
  initialize_rsc_stream_observability_state(rsc_stream_observability)

  Sync do |parent_task|
    ReactOnRailsPro::Stream.with_renderer_server_timing_collector(renderer_server_timing_collector_for_stream) do
      stream_view_containing_react_components_in_sync(
        parent_task,
        template:,
        close_stream_at_end:,
        content_type:,
        render_options:
      )
    end
  end
ensure
  @react_on_rails_pending_stream_cache_writes = nil
  restore_rsc_stream_observability_state(previous_rsc_stream_observability_state)
end