Class: Phlex::Reactive::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/phlex/reactive/response.rb

Overview

An explicit, immutable description of the ACTOR’s HTTP response to a reactive action. An action MAY return one; if it returns anything else (the legacy contract — return value ignored), the endpoint falls back to the implicit single component.to_stream_replace.

A Response governs ONLY the actor’s HTTP reply. Cross-tab updates still go through Streamable’s broadcast_*_to(…, exclude: reactive_connection_id).

Response.replace(self)                          # re-render in place (the default, explicit)
Response.replace(self).flash(:error, msg)       # surface a validation error
Response.remove(self)                           # drop the element (e.g. moderation queue)
Response.redirect(article_url(@article))        # slug changed -> Turbo.visit the new URL
Response.replace(self).stream(Totals.update(@order))  # multi-stream

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(streams: [], redirect_url: nil, render_self: true) ⇒ Response

render_self: when true (default for replace/update/with), the endpoint GUARANTEES the component’s own replace is present so its data-reactive-token-value refreshes (the client extracts the next token from the response HTML). remove/redirect set it false (nothing stays).



56
57
58
59
60
61
# File 'lib/phlex/reactive/response.rb', line 56

def initialize(streams: [], redirect_url: nil, render_self: true)
  @streams = streams.freeze
  @redirect_url = redirect_url
  @render_self = render_self
  freeze
end

Instance Attribute Details

#redirect_urlObject (readonly)

Returns the value of attribute redirect_url.



19
20
21
# File 'lib/phlex/reactive/response.rb', line 19

def redirect_url
  @redirect_url
end

#streamsObject (readonly)

Returns the value of attribute streams.



19
20
21
# File 'lib/phlex/reactive/response.rb', line 19

def streams
  @streams
end

Class Method Details

.flash_stream(_level, content, target:) ⇒ Object

Build a flash turbo-stream that appends ‘content` into a host-app container. `content` is a Phlex component instance (rendered through the configured renderer so t()/url_for work) or a ready HTML string —supplied by the caller because the render context is off-request (there is no Rails `flash`).



46
47
48
49
# File 'lib/phlex/reactive/response.rb', line 46

def flash_stream(_level, content, target:)
  html = content.is_a?(::Phlex::SGML) ? Phlex::Reactive.render(content) : content.to_s
  Phlex::Reactive.flash_builder.append(target, html: html)
end

.redirect(url) ⇒ Object

Client-side full navigation (Turbo.visit). Use when the current URL is dead (slug rename) or the outcome belongs on another page. Pass a *_url (the off-request render context has no request host for *_path).



36
# File 'lib/phlex/reactive/response.rb', line 36

def redirect(url) = new(redirect_url: url, render_self: false)

.remove(component) ⇒ Object

Remove the component’s element from the DOM. Uses the instance to_stream_remove (the component already knows its own #id — no class-builder reconstruction; works for record- and state-backed).



31
# File 'lib/phlex/reactive/response.rb', line 31

def remove(component) = new(streams: [component.to_stream_remove], render_self: false)

.replace(component) ⇒ Object

Re-render the component in place (explicit form of today’s default).



23
# File 'lib/phlex/reactive/response.rb', line 23

def replace(component) = new(streams: [component.to_stream_replace])

.update(component) ⇒ Object

Morph only inner HTML (preserves the root element + its token attr).



26
# File 'lib/phlex/reactive/response.rb', line 26

def update(component) = new(streams: [component.to_stream_update])

.with(*strings) ⇒ Object

Escape hatch / multi-stream root: zero or more raw turbo-stream strings.



39
# File 'lib/phlex/reactive/response.rb', line 39

def with(*strings) = new(streams: strings.flatten)

Instance Method Details

#flash(level, content, target: Phlex::Reactive.flash_target) ⇒ Object

Append a flash turbo-stream into a host-app container (default <div id=“flash”>, configurable via Phlex::Reactive.flash_target).



75
76
77
# File 'lib/phlex/reactive/response.rb', line 75

def flash(level, content, target: Phlex::Reactive.flash_target)
  stream(self.class.flash_stream(level, content, target:))
end

#redirect?Boolean

Returns:

  • (Boolean)


79
# File 'lib/phlex/reactive/response.rb', line 79

def redirect? = !@redirect_url.nil?

#render_self?Boolean

Returns:

  • (Boolean)


80
# File 'lib/phlex/reactive/response.rb', line 80

def render_self? = @render_self

#stream(*more) ⇒ Object

Append extra turbo-stream strings (a sibling component, a flash). Returns a NEW Response (immutable).



65
66
67
68
69
70
71
# File 'lib/phlex/reactive/response.rb', line 65

def stream(*more)
  self.class.new(
    streams: @streams + more.flatten,
    redirect_url: @redirect_url,
    render_self: @render_self
  )
end