Class: ReactOnRailsPro::StreamDecorator

Inherits:
Object
  • Object
show all
Defined in:
lib/react_on_rails_pro/stream_request.rb

Instance Method Summary collapse

Constructor Details

#initialize(component) ⇒ StreamDecorator

Returns a new instance of StreamDecorator.



20
21
22
23
24
25
26
27
28
29
# File 'lib/react_on_rails_pro/stream_request.rb', line 20

def initialize(component)
  @component = component
  # @type [Array[Proc]]
  # Proc receives 2 arguments: chunk, position
  # @param chunk [String] The chunk to be processed
  # @param position [Symbol] The position of the chunk in the stream (:first, :middle, or :last)
  # The position parameter is used by actions that add content to the beginning or end of the stream
  @actions = [] # List to store all actions
  @rescue_blocks = []
end

Instance Method Details

#appendObject

Add an append action



65
66
67
68
# File 'lib/react_on_rails_pro/stream_request.rb', line 65

def append
  @actions << ->(chunk, position) { position == :last ? "#{chunk}#{yield}" : chunk }
  self # Return self to allow chaining
end

#each_chunk(&block) ⇒ Object

rubocop:disable Metrics/CyclomaticComplexity



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/react_on_rails_pro/stream_request.rb', line 81

def each_chunk(&block) # rubocop:disable Metrics/CyclomaticComplexity
  return enum_for(:each_chunk) unless block

  first_chunk = true
  @component.each_chunk do |chunk|
    position = first_chunk ? :first : :middle
    modified_chunk = handle_chunk(chunk, position)
    yield(modified_chunk)
    first_chunk = false
  end

  # The last chunk contains the append content after the transformation
  # All transformations are applied to the append content
  last_chunk = handle_chunk("", :last)
  yield(last_chunk) unless last_chunk.empty?
rescue StandardError => e
  current_error = e
  rescue_block_index = 0
  while current_error.present? && (rescue_block_index < @rescue_blocks.size)
    begin
      @rescue_blocks[rescue_block_index].call(current_error, &block)
      current_error = nil
    rescue StandardError => inner_error
      current_error = inner_error
    end
    rescue_block_index += 1
  end
  raise current_error if current_error.present?
end

#handle_chunk(chunk, position) ⇒ Object



75
76
77
78
79
# File 'lib/react_on_rails_pro/stream_request.rb', line 75

def handle_chunk(chunk, position)
  @actions.reduce(chunk) do |acc, action|
    action.call(acc, position)
  end
end

#http_statusObject



31
32
33
34
35
# File 'lib/react_on_rails_pro/stream_request.rb', line 31

def http_status
  return @component.http_status if @component.respond_to?(:http_status)

  nil
end

#http_status_recorded?Boolean

Returns:

  • (Boolean)


37
38
39
40
41
# File 'lib/react_on_rails_pro/stream_request.rb', line 37

def http_status_recorded?
  return @component.http_status_recorded? if @component.respond_to?(:http_status_recorded?)

  false
end

#prependObject

Add a prepend action



44
45
46
47
# File 'lib/react_on_rails_pro/stream_request.rb', line 44

def prepend
  @actions << ->(chunk, position) { position == :first ? "#{yield}#{chunk}" : chunk }
  self # Return self to allow chaining
end

#rescue(&block) ⇒ Object



70
71
72
73
# File 'lib/react_on_rails_pro/stream_request.rb', line 70

def rescue(&block)
  @rescue_blocks << block
  self # Return self to allow chaining
end

#transformObject

Add a transformation action



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/react_on_rails_pro/stream_request.rb', line 50

def transform
  @actions << lambda { |chunk, position|
    if position == :last && chunk.empty?
      # Return the empty chunk without modification for the last chunk
      # This is related to the `handleChunk(:last, "")` call which gets all the appended content
      # We don't want to make an extra call to the transformer block if there is no content appended
      chunk
    else
      yield(chunk)
    end
  }
  self # Return self to allow chaining
end