Class: MaquinaStream::Frame

Inherits:
Object
  • Object
show all
Defined in:
lib/maquina_stream/frame.rb

Overview

One broadcast: what changed since the last one.

Field What is in it
appends blocks the browser has never seen, sent whole
patch unsealed blocks whose HTML moved since the last frame

Frames come out of Broadcaster. A host reads them — to assert a bandwidth budget, or to drive a transport of its own — rather than building them.

patch is a list rather than a single open block. The seal lag keeps seal_lag blocks unsealed at all times, and any of them can still change — a paragraph two blocks back becomes a heading when its underline arrives. Sending only the last one would leave the others wrong until a repair.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(seq:, appends: [], patch: [], final: false) ⇒ Frame

Builds a frame. Broadcaster does this.



32
33
34
35
36
37
# File 'lib/maquina_stream/frame.rb', line 32

def initialize(seq:, appends: [], patch: [], final: false)
  @seq = seq
  @appends = appends
  @patch = patch
  @final = final
end

Instance Attribute Details

#appends ⇒ Object (readonly)

Blocks the browser has never seen, as Block objects. Sent whole.



25
26
27
# File 'lib/maquina_stream/frame.rb', line 25

def appends
  @appends
end

#patch ⇒ Object (readonly)

Unsealed blocks whose HTML moved since the last frame, as Block objects. Applied by morph, keyed on id.



29
30
31
# File 'lib/maquina_stream/frame.rb', line 29

def patch
  @patch
end

#seq ⇒ Object (readonly)

This frame's sequence number, from the host's row. Monotonic, one per frame that actually went out. A client that sees a gap knows it missed something.



22
23
24
# File 'lib/maquina_stream/frame.rb', line 22

def seq
  @seq
end

Instance Method Details

#blocks ⇒ Object

Every block in this frame, appends first.



52
53
54
# File 'lib/maquina_stream/frame.rb', line 52

def blocks
  appends + patch
end

#bytesize ⇒ Object

The HTML this frame puts on the wire, in bytes. What the bandwidth budget is measured in.



58
59
60
# File 'lib/maquina_stream/frame.rb', line 58

def bytesize
  blocks.sum { |block| block.html.to_s.bytesize }
end

#empty? ⇒ Boolean

Whether this frame carries nothing. An empty frame is skipped, unless it is the final one.

Returns:

  • (Boolean)


47
48
49
# File 'lib/maquina_stream/frame.rb', line 47

def empty?
  appends.empty? && patch.empty?
end

#final? ⇒ Boolean

The final seal. It is marked on the wire because the repair path triggers on it: docs/design.md calls this the trigger that makes all intra-stream drift cosmetic and self-correcting, and a client cannot know a frame is the last one by looking at it.

Returns:

  • (Boolean)


43
# File 'lib/maquina_stream/frame.rb', line 43

def final? = @final

#to_h ⇒ Object

A summary: sequence, finality, and the block ids on each side. Ids rather than HTML, so it stays readable in a log.



64
65
66
67
68
69
70
71
# File 'lib/maquina_stream/frame.rb', line 64

def to_h
  {
    seq: seq,
    final: final?,
    appends: appends.map(&:id),
    patch: patch.map(&:id)
  }
end