Module: Servus::Events::Emitter

Extended by:
ActiveSupport::Concern
Included in:
Base
Defined in:
lib/servus/events/emitter.rb

Overview

Provides event emission DSL for service objects.

This module adds the ‘emits` class method to services, allowing them to declare events that will be automatically emitted on success, failure, or error.

Examples:

Basic usage

class CreateUser < Servus::Base
  emits :user_created, on: :success
  emits :user_failed, on: :failure
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.emit_result_events!(instance, result) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Emits events for a service result.

Called automatically after service execution completes. Determines the trigger type based on the result and emits all configured events.

Parameters:



27
28
29
30
# File 'lib/servus/events/emitter.rb', line 27

def self.emit_result_events!(instance, result)
  trigger = result.success? ? :success : :failure
  instance.send(:emit_events_for, trigger, result)
end

Instance Method Details

#build_event_payload(emission, result) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Builds the event payload using the configured payload builder or defaults.

Parameters:

Returns:

  • (Hash)

    the event payload



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/servus/events/emitter.rb', line 215

def build_event_payload(emission, result)
  builder = emission[:payload_builder]

  if builder.is_a?(Proc)
    instance_exec(result, &builder)
  elsif builder.is_a?(Symbol)
    # Method-based payload builder
    send(builder, result)
  elsif result.success?
    # Default for success: return data
    result.data
  else
    # Default for failure/error: return error
    result.error
  end
end

#emission_condition_met?(emission, result) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns true when all declared conditions on the emission pass.

Parameters:

Returns:

  • (Boolean)


172
173
174
175
176
177
178
179
180
# File 'lib/servus/events/emitter.rb', line 172

def emission_condition_met?(emission, result)
  if_condition = emission[:if_condition]
  unless_condition = emission[:unless_condition]

  return false if if_condition && !evaluate_emission_condition(if_condition, result)
  return false if unless_condition && evaluate_emission_condition(unless_condition, result)

  true
end

#emit_events_for(trigger, result) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Emits events for a specific trigger with the given result.

Parameters:

  • trigger (Symbol)

    the trigger type (:success, :failure, :error!)

  • result (Servus::Support::Response)

    the service result



154
155
156
157
158
159
160
161
162
# File 'lib/servus/events/emitter.rb', line 154

def emit_events_for(trigger, result)
  self.class.emissions_for(trigger).each do |emission|
    next unless emission_condition_met?(emission, result)

    payload = build_event_payload(emission, result)
    validate_event_payload!(emission[:event_name], payload)
    Servus::Events::Bus.emit(emission[:event_name], payload)
  end
end

#evaluate_emission_condition(condition, result) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Evaluates a single emission condition — either a Proc/lambda or a Symbol method reference.

Both forms receive the result object so conditions can inspect result.data, result.error, result.success?, etc.

Parameters:

Returns:

  • (Object)

    truthy or falsy value



191
192
193
# File 'lib/servus/events/emitter.rb', line 191

def evaluate_emission_condition(condition, result)
  condition.is_a?(Proc) ? instance_exec(result, &condition) : send(condition, result)
end

#validate_event_payload!(event_name, payload) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Validates the payload against the Event class’s schema registered for the event.

Parameters:

  • event_name (Symbol)

    the event name

  • payload (Hash)

    the event payload

Raises:



202
203
204
205
206
207
# File 'lib/servus/events/emitter.rb', line 202

def validate_event_payload!(event_name, payload)
  event_class = Servus::Events::Bus.event_for(event_name)
  return unless event_class

  Servus::Support::Validator.validate_event_payload!(event_class, payload)
end