class OpenUI::Rails::Stream::Bridge

Turns model output into an ordered sequence of {Envelope}s, coalescing small chunks up to ‘pending_byte_limit` and enforcing `stream_byte_limit`. Transport-agnostic: a caller broadcasts the yielded envelopes over Turbo Streams or Action Cable.

Pull sources (an Enumerable of chunks) go through {#each_envelope}; push sources (a streaming callback) use a {Writer} directly.

Attributes

library_version[R]
message_id[R]

Public Class Methods

new(message_id:, library_version: nil, configuration: OpenUI::Rails.configuration) click to toggle source

Create a bridge with message metadata and configured byte limits.

@param message_id [String] stable id shared by all frames in the stream

@param library_version [String, nil] manifest fingerprint attached to frames

@param configuration [Configuration]

@return [Bridge]

# File lib/openui/rails/stream/bridge.rb, line 25
def initialize(message_id:, library_version: nil, configuration: OpenUI::Rails.configuration)
  @message_id = message_id
  @library_version = library_version
  @configuration = configuration
end

Public Instance Methods

each_envelope(source) { |envelope| ... } click to toggle source

Yield ordered envelopes for every chunk from a pull-based source. Provider errors become a structured error envelope. Exceptions raised by the consumer block propagate to the caller.

@param source [#each] yields String chunks @yieldparam envelope [Envelope]

# File lib/openui/rails/stream/bridge.rb, line 44
def each_envelope(source)
  writer = writer()
  source = source.to_enum
  loop do
    begin
      chunk = source.next
      envelopes = writer.push(chunk)
    rescue StopIteration
      break
    rescue StandardError => error
      envelope = writer.error_for(error)
      yield envelope if envelope
      return
    end
    # Transport/consumer failures are not provider failures. Let the
    # host retry or report them without recursively broadcasting errors.
    envelopes.each { |envelope| yield envelope }
  end
  writer.finish.each { |envelope| yield envelope }
end
envelopes(source) click to toggle source

@param source [#each] yields String chunks

@return [Enumerator<Envelope>]

# File lib/openui/rails/stream/bridge.rb, line 34
def envelopes(source)
  to_enum(:each_envelope, source)
end
writer() click to toggle source

Build a stateful writer for push-based providers.

@return [Writer]

# File lib/openui/rails/stream/bridge.rb, line 68
def writer
  Writer.new(
    message_id: message_id,
    library_version: library_version,
    pending_byte_limit: @configuration.pending_byte_limit,
    stream_byte_limit: @configuration.stream_byte_limit,
    on_error: @configuration.on_error
  )
end