Class: SolidObjects::ActorChannel
- Inherits:
-
ActionCable::Channel::Base
- Object
- ActionCable::Channel::Base
- SolidObjects::ActorChannel
- Defined in:
- lib/solid_objects/actor_channel.rb,
sig/generated/lib/solid_objects/actor_channel.rbs
Instance Attribute Summary collapse
-
#component_subscriptions ⇒ Object
readonly
Returns the value of attribute component_subscriptions.
-
#payload_names ⇒ Object
readonly
Returns the value of attribute payload_names.
-
#reference ⇒ Object
readonly
Returns the value of attribute reference.
-
#scalar_observables ⇒ Object
readonly
Returns the value of attribute scalar_observables.
Instance Method Summary collapse
- #newer_payload_revision?(snapshot) ⇒ Boolean
- #receive_broadcast(stream) ⇒ void
- #refresh_outdated_components(snapshot) ⇒ void
- #scalar_observable_names(snapshot) ⇒ Array[String]
- #subscribed ⇒ void
- #transmit_state_payloads(snapshot) ⇒ void
- #validate_payload_names! ⇒ void
- #validate_scalar_observables! ⇒ void
Instance Attribute Details
#component_subscriptions ⇒ Object (readonly)
Returns the value of attribute component_subscriptions.
52 53 54 |
# File 'lib/solid_objects/actor_channel.rb', line 52 def component_subscriptions @component_subscriptions end |
#payload_names ⇒ Object (readonly)
Returns the value of attribute payload_names.
52 53 54 |
# File 'lib/solid_objects/actor_channel.rb', line 52 def payload_names @payload_names end |
#reference ⇒ Object (readonly)
Returns the value of attribute reference.
52 53 54 |
# File 'lib/solid_objects/actor_channel.rb', line 52 def reference @reference end |
#scalar_observables ⇒ Object (readonly)
Returns the value of attribute scalar_observables.
52 53 54 |
# File 'lib/solid_objects/actor_channel.rb', line 52 def scalar_observables @scalar_observables end |
Instance Method Details
#newer_payload_revision?(snapshot) ⇒ Boolean
95 96 97 98 99 100 |
# File 'lib/solid_objects/actor_channel.rb', line 95 def newer_payload_revision?(snapshot) current = @payload_revision return true unless current (current <=> [ snapshot.instance_id, snapshot.revision ]) == -1 end |
#receive_broadcast(stream) ⇒ void
This method returns an undefined value.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/solid_objects/actor_channel.rb', line 58 def receive_broadcast(stream) invalidation = TurboStreamRenderer.invalidation(stream) revision_only = invalidation && invalidation.fetch("observable_name") == PayloadBroadcast::REVISION_OBSERVABLE if !revision_only && (!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 } transmit_state_payloads(ActorSnapshot.new(reference)) end |
#refresh_outdated_components(snapshot) ⇒ void
This method returns an undefined value.
118 119 120 121 122 |
# File 'lib/solid_objects/actor_channel.rb', line 118 def refresh_outdated_components(snapshot) component_subscriptions .reconnect_refreshes(snapshot) .each { |refresh| transmit refresh } end |
#scalar_observable_names(snapshot) ⇒ Array[String]
142 143 144 145 146 |
# File 'lib/solid_objects/actor_channel.rb', line 142 def scalar_observable_names(snapshot) return scalar_observables if scalar_observables snapshot.actor_class.definition.observables.keys.map(&:to_s) end |
#subscribed ⇒ void
This method returns an undefined value.
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 46 47 48 |
# 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) = SolidObjects.configuration..call( actor_type:, actor_id:, authorization_context: connection ) return reject unless @reference = Reference.new(actor_type:, actor_id:) @scalar_observables = identity["observables"] @payload_names = identity["payloads"] validate_scalar_observables! validate_payload_names! @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) transmit_state_payloads(snapshot) rescue KeyError, JSON::ParserError, InvalidStreamToken, InvalidComponentToken, UnknownActorType reject end |
#transmit_state_payloads(snapshot) ⇒ void
This method returns an undefined value.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/solid_objects/actor_channel.rb', line 77 def transmit_state_payloads(snapshot) return if payload_names.nil? || payload_names.empty? return unless newer_payload_revision?(snapshot) payload_names.each do |name| payload = PayloadBroadcast.new( snapshot:, name:, authorization_context: connection ).call transmit TurboStreamRenderer.state_payload(payload) rescue Unauthorized next end @payload_revision = [ snapshot.instance_id, snapshot.revision ] end |
#validate_payload_names! ⇒ void
This method returns an undefined value.
103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/solid_objects/actor_channel.rb', line 103 def validate_payload_names! return unless payload_names broadcasts = SolidObjects .registry .fetch(reference.actor_type) .definition .payload_broadcasts unknown = payload_names.find { |name| !broadcasts.key?(name.to_sym) } return unless unknown raise InvalidStreamToken, "unknown payload broadcast #{unknown.inspect}" end |
#validate_scalar_observables! ⇒ void
This method returns an undefined value.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/solid_objects/actor_channel.rb', line 125 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 |