module Turbo::Broadcastable

def broadcast_action(action, target: broadcast_target_default, attributes: {}, **rendering)

Same as #broadcast_action_to, but the designated stream is automatically set to the current model.
def broadcast_action(action, target: broadcast_target_default, attributes: {}, **rendering)
  broadcast_action_to self, action: action, target: target, attributes: attributes, **rendering
end

def broadcast_action_later(action:, target: broadcast_target_default, attributes: {}, **rendering)

Same as #broadcast_action_later_to, but the designated stream is automatically set to the current model.
def broadcast_action_later(action:, target: broadcast_target_default, attributes: {}, **rendering)
  broadcast_action_later_to self, action: action, target: target, attributes: attributes, **rendering
end

def broadcast_action_later_to(*streamables, action:, target: broadcast_target_default, attributes: {}, **rendering)

Same as broadcast_action_to but run asynchronously via a Turbo::Streams::BroadcastJob.
def broadcast_action_later_to(*streamables, action:, target: broadcast_target_default, attributes: {}, **rendering)
  Turbo::StreamsChannel.broadcast_action_later_to(*streamables, action: action, attributes: attributes, **extract_options_and_add_target(rendering, target: target)) unless suppressed_turbo_broadcasts?
end

def broadcast_action_to(*streamables, action:, target: broadcast_target_default, attributes: {}, **rendering)

clearance.broadcast_action_to examiner.identity, :clearances, action: :prepend, target: "clearances"
# to the stream named "identity:2:clearances"
# Sends

Broadcast a named action, allowing for dynamic dispatch, instead of using the concrete action methods. Examples:
def broadcast_action_to(*streamables, action:, target: broadcast_target_default, attributes: {}, **rendering)
  Turbo::StreamsChannel.broadcast_action_to(*streamables, action: action, attributes: attributes, **extract_options_and_add_target(rendering, target: target)) unless suppressed_turbo_broadcasts?
end

def broadcast_after_to(*streamables, target: nil, targets: nil, **rendering)

partial: "clearances/other_partial", locals: { a: 1 }
clearance.broadcast_after_to examiner.identity, :clearances, target: "clearance_5",
# to the stream named "identity:2:clearances"
# Sends

clearance.broadcast_after_to examiner.identity, :clearances, target: "clearance_5"
# to the stream named "identity:2:clearances"
# Sends

appending named arguments to the call. Examples:
for subscribers of the stream name identified by the passed streamables. The rendering parameters can be set by
Insert a rendering of this broadcastable model after the target identified by it's dom id passed as target
def broadcast_after_to(*streamables, target: nil, targets: nil, **rendering)
  raise ArgumentError, "at least one of target or targets is required" unless target || targets
  Turbo::StreamsChannel.broadcast_after_to(*streamables, **extract_options_and_add_target(rendering.merge(target: target, targets: targets)))
end

def broadcast_append(target: broadcast_target_default, **rendering)

Same as #broadcast_append_to, but the designated stream is automatically set to the current model.
def broadcast_append(target: broadcast_target_default, **rendering)
  broadcast_append_to self, target: target, **rendering
end

def broadcast_append_later(target: broadcast_target_default, **rendering)

Same as #broadcast_append_later_to, but the designated stream is automatically set to the current model.
def broadcast_append_later(target: broadcast_target_default, **rendering)
  broadcast_append_later_to self, target: target, **rendering
end

def broadcast_append_later_to(*streamables, target: broadcast_target_default, **rendering)

Same as broadcast_append_to but run asynchronously via a Turbo::Streams::BroadcastJob.
def broadcast_append_later_to(*streamables, target: broadcast_target_default, **rendering)
  Turbo::StreamsChannel.broadcast_append_later_to(*streamables, **extract_options_and_add_target(rendering, target: target)) unless suppressed_turbo_broadcasts?
end

def broadcast_append_to(*streamables, target: broadcast_target_default, **rendering)

partial: "clearances/other_partial", locals: { a: 1 }
clearance.broadcast_append_to examiner.identity, :clearances, target: "clearances",
# to the stream named "identity:2:clearances"
# Sends

clearance.broadcast_append_to examiner.identity, :clearances, target: "clearances"
# to the stream named "identity:2:clearances"
# Sends

appending named arguments to the call. Examples:
for subscribers of the stream name identified by the passed streamables. The rendering parameters can be set by
Append a rendering of this broadcastable model to the target identified by it's dom id passed as target
def broadcast_append_to(*streamables, target: broadcast_target_default, **rendering)
  Turbo::StreamsChannel.broadcast_append_to(*streamables, **extract_options_and_add_target(rendering, target: target)) unless suppressed_turbo_broadcasts?
end

def broadcast_before_to(*streamables, target: nil, targets: nil, **rendering)

partial: "clearances/other_partial", locals: { a: 1 }
clearance.broadcast_before_to examiner.identity, :clearances, target: "clearance_5",
# to the stream named "identity:2:clearances"
# Sends

clearance.broadcast_before_to examiner.identity, :clearances, target: "clearance_5"
# to the stream named "identity:2:clearances"
# Sends

appending named arguments to the call. Examples:
for subscribers of the stream name identified by the passed streamables. The rendering parameters can be set by
Insert a rendering of this broadcastable model before the target identified by it's dom id passed as target
def broadcast_before_to(*streamables, target: nil, targets: nil, **rendering)
  raise ArgumentError, "at least one of target or targets is required" unless target || targets
  Turbo::StreamsChannel.broadcast_before_to(*streamables, **extract_options_and_add_target(rendering.merge(target: target, targets: targets)))
end

def broadcast_prepend(target: broadcast_target_default, **rendering)

Same as #broadcast_prepend_to, but the designated stream is automatically set to the current model.
def broadcast_prepend(target: broadcast_target_default, **rendering)
  broadcast_prepend_to self, target: target, **rendering
end

def broadcast_prepend_later(target: broadcast_target_default, **rendering)

Same as #broadcast_prepend_later_to, but the designated stream is automatically set to the current model.
def broadcast_prepend_later(target: broadcast_target_default, **rendering)
  broadcast_prepend_later_to self, target: target, **rendering
end

def broadcast_prepend_later_to(*streamables, target: broadcast_target_default, **rendering)

Same as broadcast_prepend_to but run asynchronously via a Turbo::Streams::BroadcastJob.
def broadcast_prepend_later_to(*streamables, target: broadcast_target_default, **rendering)
  Turbo::StreamsChannel.broadcast_prepend_later_to(*streamables, **extract_options_and_add_target(rendering, target: target)) unless suppressed_turbo_broadcasts?
end

def broadcast_prepend_to(*streamables, target: broadcast_target_default, **rendering)

partial: "clearances/other_partial", locals: { a: 1 }
clearance.broadcast_prepend_to examiner.identity, :clearances, target: "clearances",
# to the stream named "identity:2:clearances"
# Sends

clearance.broadcast_prepend_to examiner.identity, :clearances, target: "clearances"
# to the stream named "identity:2:clearances"
# Sends

appending named arguments to the call. Examples:
for subscribers of the stream name identified by the passed streamables. The rendering parameters can be set by
Prepend a rendering of this broadcastable model to the target identified by it's dom id passed as target
def broadcast_prepend_to(*streamables, target: broadcast_target_default, **rendering)
  Turbo::StreamsChannel.broadcast_prepend_to(*streamables, **extract_options_and_add_target(rendering, target: target)) unless suppressed_turbo_broadcasts?
end

def broadcast_refresh

Same as #broadcast_refresh_to, but the designated stream is automatically set to the current model.
def broadcast_refresh
  broadcast_refresh_to self
end

def broadcast_refresh_later

Same as #broadcast_refresh_later_to, but the designated stream is automatically set to the current model.
def broadcast_refresh_later
  broadcast_refresh_later_to self
end

def broadcast_refresh_later_to(*streamables)

Same as broadcast_refresh_to but run asynchronously via a Turbo::Streams::BroadcastJob.
def broadcast_refresh_later_to(*streamables)
  Turbo::StreamsChannel.broadcast_refresh_later_to(*streamables, request_id: Turbo.current_request_id) unless suppressed_turbo_broadcasts?
end

def broadcast_refresh_to(*streamables)

clearance.broadcast_refresh_to examiner.identity, :clearances
# Sends to the stream named "identity:2:clearances"

Broadcast a "page refresh" to the stream name identified by the passed streamables. Example:
def broadcast_refresh_to(*streamables)
  Turbo::StreamsChannel.broadcast_refresh_to(*streamables) unless suppressed_turbo_broadcasts?
end

def broadcast_remove(**rendering)

Same as #broadcast_remove_to, but the designated stream is automatically set to the current model.
def broadcast_remove(**rendering)
  broadcast_remove_to self, **rendering
end

def broadcast_remove_to(*streamables, target: self, **rendering)

clearance.broadcast_remove_to examiner.identity, :clearances
# Sends to the stream named "identity:2:clearances"

Example:
Remove this broadcastable model from the dom for subscribers of the stream name identified by the passed streamables.
def broadcast_remove_to(*streamables, target: self, **rendering)
  Turbo::StreamsChannel.broadcast_remove_to(*streamables, **extract_options_and_add_target(rendering, target: target)) unless suppressed_turbo_broadcasts?
end

def broadcast_render(**rendering)

be using +broadcast_render_later+, unless you specifically know why synchronous rendering is needed.
desireable for model callbacks, certainly not if those callbacks are inside of a transaction. Most of the time you should
Note that rendering inline via this method will cause template rendering to happen synchronously. That is usually not

...to the stream named "entry:5".




Sends:

<%= turbo_stream.append "entries", entry if entry.active? %>

<%= turbo_stream.remove entry %>
# Template: entries/_entry.turbo_stream.erb

Render a turbo stream template with this broadcastable model passed as the local variable. Example:
def broadcast_render(**rendering)
  broadcast_render_to self, **rendering
end

def broadcast_render_later(**rendering)

Same as broadcast_render_to but run asynchronously via a Turbo::Streams::BroadcastJob.
def broadcast_render_later(**rendering)
  broadcast_render_later_to self, **rendering
end

def broadcast_render_later_to(*streamables, **rendering)

streamables.
Same as broadcast_render_later but run with the added option of naming the stream using the passed
def broadcast_render_later_to(*streamables, **rendering)
  Turbo::StreamsChannel.broadcast_render_later_to(*streamables, **extract_options_and_add_target(rendering)) unless suppressed_turbo_broadcasts?
end

def broadcast_render_to(*streamables, **rendering)

be using +broadcast_render_later_to+, unless you specifically know why synchronous rendering is needed.
desireable for model callbacks, certainly not if those callbacks are inside of a transaction. Most of the time you should
Note that rendering inline via this method will cause template rendering to happen synchronously. That is usually not

streamables.
Same as broadcast_render but run with the added option of naming the stream using the passed
def broadcast_render_to(*streamables, **rendering)
  Turbo::StreamsChannel.broadcast_render_to(*streamables, **extract_options_and_add_target(rendering, target: self)) unless suppressed_turbo_broadcasts?
end

def broadcast_rendering_with_defaults(options)

def broadcast_rendering_with_defaults(options)
  options.tap do |o|
    # Add the current instance into the locals with the element name (which is the un-namespaced name)
    # as the key. This parallels how the ActionView::ObjectRenderer would create a local variable.
    o[:locals] = (o[:locals] || {}).reverse_merge(model_name.element.to_sym => self)
    if o[:html] || o[:partial]
      return o
    elsif o[:template] || o[:renderable]
      o[:layout] = false
    elsif o[:render] == false
      return o
    else
      # if none of these options are passed in, it will set a partial from #to_partial_path
      o[:partial] ||= to_partial_path
    end
  end
end

def broadcast_replace(**rendering)

Same as #broadcast_replace_to, but the designated stream is automatically set to the current model.
def broadcast_replace(**rendering)
  broadcast_replace_to self, **rendering
end

def broadcast_replace_later(**rendering)

Same as #broadcast_replace_later_to, but the designated stream is automatically set to the current model.
def broadcast_replace_later(**rendering)
  broadcast_replace_later_to self, **rendering
end

def broadcast_replace_later_to(*streamables, **rendering)

Same as broadcast_replace_to but run asynchronously via a Turbo::Streams::BroadcastJob.
def broadcast_replace_later_to(*streamables, **rendering)
  Turbo::StreamsChannel.broadcast_replace_later_to(*streamables, **extract_options_and_add_target(rendering, target: self)) unless suppressed_turbo_broadcasts?
end

def broadcast_replace_to(*streamables, **rendering)

clearance.broadcast_replace_to examiner.identity, :clearance, attributes: { method: :morph }, partial: "clearances/other_partial", locals: { a: 1 }
# to the stream named "identity:2:clearances"
# Sends

clearance.broadcast_replace_to examiner.identity, :clearances, partial: "clearances/other_partial", locals: { a: 1 }
# to the stream named "identity:2:clearances"
# Sends

clearance.broadcast_replace_to examiner.identity, :clearances
# to the stream named "identity:2:clearances"
# Sends

streamables. The rendering parameters can be set by appending named arguments to the call. Examples:
Replace this broadcastable model in the dom for subscribers of the stream name identified by the passed
def broadcast_replace_to(*streamables, **rendering)
  Turbo::StreamsChannel.broadcast_replace_to(*streamables, **extract_options_and_add_target(rendering, target: self)) unless suppressed_turbo_broadcasts?
end

def broadcast_target_default

def broadcast_target_default
  self.class.broadcast_target_default
end

def broadcast_update(**rendering)

Same as #broadcast_update_to, but the designated stream is automatically set to the current model.
def broadcast_update(**rendering)
  broadcast_update_to self, **rendering
end

def broadcast_update_later(**rendering)

Same as #broadcast_update_later_to, but the designated stream is automatically set to the current model.
def broadcast_update_later(**rendering)
  broadcast_update_later_to self, **rendering
end

def broadcast_update_later_to(*streamables, **rendering)

Same as broadcast_update_to but run asynchronously via a Turbo::Streams::BroadcastJob.
def broadcast_update_later_to(*streamables, **rendering)
  Turbo::StreamsChannel.broadcast_update_later_to(*streamables, **extract_options_and_add_target(rendering, target: self)) unless suppressed_turbo_broadcasts?
end

def broadcast_update_to(*streamables, **rendering)

clearance.broadcast_update_to examiner.identity, :clearances, attributes: { method: :morph }, partial: "clearances/other_partial", locals: { a: 1 }
# to the stream named "identity:2:clearances"
# sends

clearance.broadcast_update_to examiner.identity, :clearances, partial: "clearances/other_partial", locals: { a: 1 }
# to the stream named "identity:2:clearances"
# Sends

clearance.broadcast_update_to examiner.identity, :clearances
# to the stream named "identity:2:clearances"
# Sends

streamables. The rendering parameters can be set by appending named arguments to the call. Examples:
Update this broadcastable model in the dom for subscribers of the stream name identified by the passed
def broadcast_update_to(*streamables, **rendering)
  Turbo::StreamsChannel.broadcast_update_to(*streamables, **extract_options_and_add_target(rendering, target: self)) unless suppressed_turbo_broadcasts?
end

def extract_options_and_add_target(rendering = {}, target: broadcast_target_default)

def extract_options_and_add_target(rendering = {}, target: broadcast_target_default)
  broadcast_rendering_with_defaults(rendering).tap do |options|
    options[:target] = target if !options.key?(:target) && !options.key?(:targets)
  end
end