Module: Upkeep::Rails::ClientSubscription

Defined in:
lib/upkeep/rails/client_subscription.rb

Constant Summary collapse

CHANNEL =
"Upkeep::Rails::Cable::Channel"
ID_HEADER =
"X-Upkeep-Subscription-Id"
TOKEN_HEADER =
"X-Upkeep-Subscription-Token"
CHANNEL_HEADER =
"X-Upkeep-Subscription-Channel"
STREAM_HEADER =
"X-Upkeep-Subscription-Stream"
ACTION_HEADER =
"X-Upkeep-Subscription-Action"

Class Method Summary collapse

Class Method Details

.headers_for(identity:, subscription:) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'lib/upkeep/rails/client_subscription.rb', line 38

def headers_for(identity:, subscription:)
  payload = payload_for(identity: identity, subscription: subscription)
  {
    ID_HEADER => payload.fetch("subscription-id"),
    TOKEN_HEADER => payload.fetch("activation-token"),
    CHANNEL_HEADER => payload.fetch("channel"),
    STREAM_HEADER => payload.fetch("stream-name")
  }
end

.inject(html, identity:, subscription:) ⇒ Object



17
18
19
20
21
# File 'lib/upkeep/rails/client_subscription.rb', line 17

def inject(html, identity:, subscription:)
  marker = marker_for(identity: identity, subscription: subscription)
  insert_before_closing("body", html, marker) ||
    "#{html}#{marker}"
end

.insert_before_closing(tag, html, marker) ⇒ Object



57
58
59
60
61
62
# File 'lib/upkeep/rails/client_subscription.rb', line 57

def insert_before_closing(tag, html, marker)
  index = html.rindex(%(</#{tag}>)) || html.rindex(%(</#{tag.upcase}>))
  return unless index

  "#{html[0...index]}#{marker}#{html[index..]}"
end

.marker_for(identity:, subscription:) ⇒ Object

The payload travels as attributes (like turbo-cable-stream-source), never as text content, so it can't show up as page text when JS is absent.



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/upkeep/rails/client_subscription.rb', line 25

def marker_for(identity:, subscription:)
  attributes = payload_for(identity: identity, subscription: subscription).merge(
    "id" => "upkeep-subscription-source"
  )

  [
    %(<upkeep-subscription-source ),
    attributes.map { |name, value| %(#{name}="#{CGI.escapeHTML(value.to_s)}") }.join(" "),
    %( hidden style="display:none" data-upkeep-subscription>),
    %(</upkeep-subscription-source>)
  ].join
end

.payload_for(identity:, subscription:) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/upkeep/rails/client_subscription.rb', line 48

def payload_for(identity:, subscription:)
  {
    "channel" => CHANNEL,
    "subscription-id" => subscription.id,
    "activation-token" => ActivationToken.generate(subscription),
    "stream-name" => identity.stream_name
  }
end