Class: SolidObjects::ComponentSubscriptions

Inherits:
Object
  • Object
show all
Defined in:
lib/solid_objects/component_subscriptions.rb,
sig/generated/lib/solid_objects/component_subscriptions.rbs

Constant Summary collapse

MAXIMUM_COMPONENTS =

Returns:

  • (::Integer)
50
MAXIMUM_SERIALIZED_BYTES =

Returns:

  • (::Integer)
1_048_576

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(registrations) ⇒ ComponentSubscriptions

Returns a new instance of ComponentSubscriptions.

RBS:

  • (Array[ComponentRegistration]) -> void

Parameters:



39
40
41
42
43
44
# File 'lib/solid_objects/component_subscriptions.rb', line 39

def initialize(registrations)
  @registrations = registrations
  @revisions = registrations.to_h do |registration|
    [ registration.dom_id, registration.revision_key ]
  end
end

Instance Attribute Details

#registrationsObject (readonly)

Returns the value of attribute registrations.

Returns:

  • (Object)


91
92
93
# File 'lib/solid_objects/component_subscriptions.rb', line 91

def registrations
  @registrations
end

#revisionsObject (readonly)

Returns the value of attribute revisions.

Returns:

  • (Object)


91
92
93
# File 'lib/solid_objects/component_subscriptions.rb', line 91

def revisions
  @revisions
end

Class Method Details

.parse(serialized, reference:) ⇒ ComponentSubscriptions

RBS:

  • (String?, reference: Reference) -> ComponentSubscriptions

Parameters:

Returns:



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
# File 'lib/solid_objects/component_subscriptions.rb', line 12

def self.parse(serialized, reference:)
  return new([]) unless serialized
  unless serialized.is_a?(String) &&
      serialized.bytesize <= MAXIMUM_SERIALIZED_BYTES
    raise InvalidComponentToken, "invalid actor component registrations"
  end

  tokens = JSON.parse(serialized)
  unless tokens.is_a?(Array) &&
      tokens.length <= MAXIMUM_COMPONENTS &&
      tokens.all? { |token| token.is_a?(String) }
    raise InvalidComponentToken, "invalid actor component registrations"
  end

  registrations = tokens.map do |token|
    ComponentRegistration.from_token(token).tap do |registration|
      validate_identity!(registration, reference)
    end
  end
  if registrations.map(&:dom_id).uniq.length != registrations.length
    raise InvalidComponentToken, "duplicate actor component registration"
  end

  new(registrations)
end

Instance Method Details

#newer_revision?(dom_id, instance_id, revision) ⇒ Boolean

RBS:

  • (String, Integer, Integer) -> bool

Parameters:

  • (String)
  • (Integer)
  • (Integer)

Returns:

  • (Boolean)


104
105
106
107
# File 'lib/solid_objects/component_subscriptions.rb', line 104

def newer_revision?(dom_id, instance_id, revision)
  current = revisions.fetch(dom_id)
  (current <=> [ instance_id, revision ]) == -1
end

#reconnect_refreshes(snapshot) ⇒ Array[String]

RBS:

  • (ActorSnapshot) -> Array[String]

Parameters:

Returns:

  • (Array[String])


64
65
66
67
68
69
70
71
72
73
74
# File 'lib/solid_objects/component_subscriptions.rb', line 64

def reconnect_refreshes(snapshot)
  registrations.filter_map do |registration|
    next unless newer_revision?(
      registration.dom_id,
      snapshot.instance_id,
      snapshot.revision
    )

    refresh(registration, snapshot.instance_id, snapshot.revision)
  end
end

#refresh(registration, instance_id, revision) ⇒ String

RBS:

  • (ComponentRegistration, Integer, Integer) -> String

Parameters:

Returns:

  • (String)


94
95
96
97
98
99
100
101
# File 'lib/solid_objects/component_subscriptions.rb', line 94

def refresh(registration, instance_id, revision)
  revisions[registration.dom_id] = [ instance_id, revision ]
  TurboStreamRenderer.component_refresh(
    registration,
    instance_id,
    revision
  )
end

#refreshes_for(invalidation) ⇒ Array[String]

RBS:

  • (Hash[String, untyped]) -> Array[String]

Parameters:

  • (Hash[String, untyped])

Returns:

  • (Array[String])


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/solid_objects/component_subscriptions.rb', line 47

def refreshes_for(invalidation)
  observable_name = invalidation.fetch("observable_name")
  instance_id = invalidation.fetch("instance_id")
  revision = invalidation.fetch("revision")
  registrations.filter_map do |registration|
    next unless registration.dependencies.include?(observable_name)
    next unless newer_revision?(
      registration.dom_id,
      instance_id,
      revision
    )

    refresh(registration, instance_id, revision)
  end
end