Module: ReactOnRailsPro::Stream

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

Instance Method Summary collapse

Instance Method Details

#stream_view_containing_react_components(template:, close_stream_at_end: true, **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).

  • render_options (Hash)

    Additional options to pass to render_to_string.

See Also:

  • ReactOnRails::Helper#stream_react_component


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/react_on_rails_pro/concerns/stream.rb', line 33

def stream_view_containing_react_components(template:, close_stream_at_end: true, **render_options)
  require "async"
  require "async/barrier"
  require "async/limited_queue"

  Sync do |parent_task|
    # Initialize async primitives for concurrent component streaming
    @async_barrier = Async::Barrier.new
    buffer_size = ReactOnRailsPro.configuration.concurrent_component_streaming_buffer_size
    @main_output_queue = Async::LimitedQueue.new(buffer_size)

    # Render template - components will start streaming immediately
    template_string = render_to_string(template: template, **render_options)
    # View may contain extra newlines, chunk already contains a newline
    # Having multiple newlines between chunks causes hydration errors
    # So we strip extra newlines from the template string and add a single newline
    response.stream.write(template_string)

    begin
      drain_streams_concurrently(parent_task)
      # Do not close the response stream in an ensure block.
      # If an error occurs we may need the stream open to send diagnostic/error details
      # (for example, ApplicationController#rescue_from in the dummy app).
      response.stream.close if close_stream_at_end
    end
  end
end