Class: SolidObjects::ActorChannel

Inherits:
ActionCable::Channel::Base show all
Defined in:
lib/solid_objects/actor_channel.rb,
sig/generated/lib/solid_objects/actor_channel.rbs

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#component_subscriptionsObject (readonly)

Returns the value of attribute component_subscriptions.

Returns:

  • (Object)


49
50
51
# File 'lib/solid_objects/actor_channel.rb', line 49

def component_subscriptions
  @component_subscriptions
end

#referenceObject (readonly)

Returns the value of attribute reference.

Returns:

  • (Object)


49
50
51
# File 'lib/solid_objects/actor_channel.rb', line 49

def reference
  @reference
end

#scalar_observablesObject (readonly)

Returns the value of attribute scalar_observables.

Returns:

  • (Object)


49
50
51
# File 'lib/solid_objects/actor_channel.rb', line 49

def scalar_observables
  @scalar_observables
end

Instance Method Details

#receive_broadcast(stream) ⇒ void

This method returns an undefined value.

RBS:

  • (String) -> void

Parameters:

  • (String)


52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/solid_objects/actor_channel.rb', line 52

def receive_broadcast(stream)
  invalidation = TurboStreamRenderer.invalidation(stream)
  if !invalidation ||
      scalar_observables.nil? ||
      scalar_observables.include?(invalidation.fetch("observable_name"))
    transmit stream
  end
  return unless invalidation

  component_subscriptions
    .refreshes_for(invalidation)
    .each { |refresh| transmit refresh }
end

#refresh_outdated_components(snapshot) ⇒ void

This method returns an undefined value.

RBS:

  • (ActorSnapshot) -> void

Parameters:



67
68
69
70
71
# File 'lib/solid_objects/actor_channel.rb', line 67

def refresh_outdated_components(snapshot)
  component_subscriptions
    .reconnect_refreshes(snapshot)
    .each { |refresh| transmit refresh }
end

#scalar_observable_names(snapshot) ⇒ Array[String]

RBS:

  • (ActorSnapshot) -> Array[String]

Parameters:

Returns:

  • (Array[String])


91
92
93
94
95
# File 'lib/solid_objects/actor_channel.rb', line 91

def scalar_observable_names(snapshot)
  return scalar_observables if scalar_observables

  snapshot.actor_class.definition.observables.keys.map(&:to_s)
end

#subscribedvoid

This method returns an undefined value.

RBS:

  • () -> void



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/solid_objects/actor_channel.rb', line 8

def subscribed
  identity = StreamToken.verify(params.fetch("token"))
  actor_type = identity.fetch("actor_type")
  actor_id = identity.fetch("actor_id")
  SolidObjects.registry.fetch(actor_type)
  authorized = SolidObjects.configuration.authorize_subscription.call(
    actor_type:,
    actor_id:,
    authorization_context: connection
  )
  return reject unless authorized

  @reference = Reference.new(actor_type:, actor_id:)
  @scalar_observables = identity["observables"]
  validate_scalar_observables!
  @component_subscriptions = ComponentSubscriptions.parse(
    params["components"],
    reference:
  )
  stream_from StreamName.for(reference), coder: ActiveSupport::JSON do |stream|
    receive_broadcast(stream)
  end
  snapshot = ActorSnapshot.new(reference)
  scalar_observable_names(snapshot).each do |name|
    transmit TurboStreamRenderer.observable_value(
      reference,
      name,
      snapshot.observable_value(name)
    )
  end
  refresh_outdated_components(snapshot)
rescue KeyError,
  JSON::ParserError,
  InvalidStreamToken,
  InvalidComponentToken,
  UnknownActorType
  reject
end

#validate_scalar_observables!void

This method returns an undefined value.

RBS:

  • () -> void



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/solid_objects/actor_channel.rb', line 74

def validate_scalar_observables!
  return unless scalar_observables

  observables = SolidObjects
    .registry
    .fetch(reference.actor_type)
    .definition
    .observables
  unknown = scalar_observables.find do |name|
    !observables.key?(name.to_sym)
  end
  return unless unknown

  raise InvalidStreamToken, "unknown scalar observable #{unknown.inspect}"
end