Class: Ruact::RenderPipeline

Inherits:
Object
  • Object
show all
Defined in:
lib/ruact/render_pipeline.rb

Overview

Orchestrates the full server component render:

ERB source → (preprocessor) → evaluated HTML → (HtmlConverter) → ReactElement tree
                                                                 → (Flight::Renderer) → wire bytes

Two entry points:

call/stream — full pipeline from ERB source (used in unit tests and legacy path)
from_html   — takes pre-rendered HTML from ActionView (used by Controller#rsc_render)

Instance Method Summary collapse

Constructor Details

#initialize(manifest, controller_path: nil, logger: nil) ⇒ RenderPipeline

Returns a new instance of RenderPipeline.



14
15
16
17
18
# File 'lib/ruact/render_pipeline.rb', line 14

def initialize(manifest, controller_path: nil, logger: nil)
  @manifest         = manifest
  @controller_path  = controller_path
  @logger           = logger
end

Instance Method Details

#call(erb_source, binding_context) ⇒ Object

Render ERB source within a given binding, return Flight wire format string. Deferred chunk delays are skipped — suitable for buffered responses (HTML shell).



22
23
24
# File 'lib/ruact/render_pipeline.rb', line 22

def call(erb_source, binding_context)
  _stream(erb_source, binding_context, streaming: false).to_a.join
end

#from_html(html, streaming: false) ⇒ Object

Convert pre-rendered HTML (from ActionView) to Flight wire rows.

IMPORTANT — Eager registry capture: ComponentRegistry.components is read immediately when this method is called, before the Enumerator is returned. This allows the caller to call ComponentRegistry.reset right after from_html returns (inside an ensure block) without affecting the captured registry.

The returned Enumerator does NOT reference ComponentRegistry at all —only the eagerly-captured registry local variable.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ruact/render_pipeline.rb', line 41

def from_html(html, streaming: false)
  registry = ComponentRegistry.components.map do |entry|
    ref = @manifest.reference_for(entry[:name], controller_path: @controller_path)
    { token: entry[:token], name: entry[:name], ref: ref, props: entry[:props] }
  end
  strict = Ruact.config.strict_serialization
  warning_cb = as_json_warning_callback

  Enumerator.new do |y|
    root_element = HtmlConverter.convert(html, registry)
    Flight::Renderer.each(root_element, @manifest,
                          strict_serialization: strict,
                          on_as_json_warning: warning_cb,
                          streaming: streaming) { |row| y << row }
  end
end

#stream(erb_source, binding_context) ⇒ Object

Render ERB source and return an Enumerator that yields Flight rows one at a time. Deferred chunk delays ARE applied — suitable for ActionController::Live streaming.



28
29
30
# File 'lib/ruact/render_pipeline.rb', line 28

def stream(erb_source, binding_context)
  _stream(erb_source, binding_context, streaming: true)
end