live 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf47630cac82b5611f454d7c61b1db67d8802c91eabc819d44d2e1a82ffd1d96
4
- data.tar.gz: ce5bcd2dd5a5bc0c98357eb963aaa38ff83c4e312da85c0f3b4e79ca546e6d72
3
+ metadata.gz: 35d2a64d31fa83855d4dd194f497ef9c948c9d03fde7fabf73256bdccec8d03e
4
+ data.tar.gz: 161456e3ee4ded05ff1c6e58e81d78a098ed28a19d33d9da4217f2d4bc190db1
5
5
  SHA512:
6
- metadata.gz: cd5eaca0a5038361c60d13de5bc8b5e8e5ce66f0e828c74c0c199d6a8d9706bee31fbeff1365155b41b59241c2be4f405f6d1186c44b928510d1d94ad7e42000
7
- data.tar.gz: 0f0956b2f4a4d79af54ee01e965585d370633eac1ad23ded24c817e43f0b7b8dd681a5187607fe2fdf4fa52be385f4c20ec25a09c55ceee5c00fe846c8a4cde1
6
+ metadata.gz: ba9b1e779713e8330e440d1d3f3fbb67b4ef41708e0d549828790d135f4e7e80e4420292e923dad5941be0e9ff538c6184383600773490fd6ee36ec8e796228c
7
+ data.tar.gz: f1f9df657949d4c56d5b99ccb2a280e4f9599d45152a1a96db3ca039401593d48df0fbe5e510d749f98e719b768fdd5fa9211bd58a25fa0c48e40b23fd137954
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/live/element.rb CHANGED
@@ -79,7 +79,7 @@ module Live
79
79
  def rpc(*arguments)
80
80
  if @page
81
81
  # This update might not be sent right away. Therefore, mutable arguments may be serialized to JSON at a later time (or never). This could be a race condition:
82
- @page.updates.enqueue(arguments)
82
+ @page.enqueue(arguments)
83
83
  else
84
84
  # This is a programming error, as it probably means the element is still part of the logic of the server side (e.g. async loop), but it is not bound to a page, so there is nothing to update/access/rpc.
85
85
  raise PageError, "Element is not bound to a page, make sure to implement #close!"
@@ -138,11 +138,17 @@ module Live
138
138
  builder.text(self.class.name)
139
139
  end
140
140
 
141
+ def append_markup(output)
142
+ build_markup(::XRB::Builder.new(output))
143
+ end
144
+
145
+ def build_markup(builder)
146
+ render(builder)
147
+ end
148
+
141
149
  # @returns [Object] The generated HTML.
142
150
  def to_html
143
- XRB::Builder.fragment do |builder|
144
- render(builder)
145
- end
151
+ XRB::Builder.fragment(&self.method(:build_markup))
146
152
  end
147
153
 
148
154
  # Convenience method for rendering the view as a string.
data/lib/live/page.rb CHANGED
@@ -27,9 +27,6 @@ module Live
27
27
  @updates = Async::Queue.new
28
28
  end
29
29
 
30
- # The queue of outstanding events to be sent to the client.
31
- attr :updates
32
-
33
30
  # Bind a client-side element to a server side element.
34
31
  # @parameter element [Live::Element] The element to bind.
35
32
  def bind(element)
@@ -84,6 +81,10 @@ module Live
84
81
  end
85
82
  end
86
83
 
84
+ def enqueue(update)
85
+ @updates.enqueue(::Protocol::WebSocket::TextMessage.generate(update))
86
+ end
87
+
87
88
  # Process a single incoming message from the network.
88
89
  def process_message(message)
89
90
  case message[0]
@@ -93,7 +94,7 @@ module Live
93
94
  self.bind(element)
94
95
  else
95
96
  Console.warn(self, "Could not resolve element:", message)
96
- @updates.enqueue(["error", message[1], "Could not resolve element!"])
97
+ self.enqueue(["error", message[1], "Could not resolve element!"])
97
98
  end
98
99
  when "unbind"
99
100
  # Unbind a client-side element from a server-side element.
@@ -101,7 +102,7 @@ module Live
101
102
  element.close unless @attached.key?(message[1])
102
103
  else
103
104
  Console.warn(self, "Could not unbind element:", message)
104
- @updates.enqueue(["error", message[1], "Could not unbind element!"])
105
+ self.enqueue(["error", message[1], "Could not unbind element!"])
105
106
  end
106
107
  when "event"
107
108
  # Handle an event from the client.
@@ -113,22 +114,43 @@ module Live
113
114
 
114
115
  # Run the event handling loop with the given websocket connection.
115
116
  # @parameter connection [Async::WebSocket::Connection]
116
- def run(connection)
117
+ def run(connection, keep_alive: 10)
117
118
  Sync do |task|
119
+ last_update = Async::Clock.now
120
+
118
121
  queue_task = task.async do
119
122
  while update = @updates.dequeue
120
- ::Protocol::WebSocket::TextMessage.generate(update).send(connection)
123
+ update.send(connection)
121
124
 
122
125
  # Flush the output if there are no more updates:
123
- connection.flush if @updates.empty?
126
+ if @updates.empty?
127
+ connection.flush
128
+ end
129
+ end
130
+ end
131
+
132
+ keep_alive_task = task.async do
133
+ while true
134
+ sleep(keep_alive)
135
+
136
+ duration = Async::Clock.now - last_update
137
+
138
+ # We synchronize all writes to the update queue:
139
+ if duration > keep_alive
140
+ @updates.enqueue(::Protocol::WebSocket::PingMessage.new)
141
+ end
124
142
  end
125
143
  end
126
144
 
127
145
  while message = connection.read
146
+ last_update = Async::Clock.now
128
147
  process_message(message.parse)
129
148
  end
130
149
  ensure
150
+ keep_alive_task&.stop
151
+
131
152
  self.close
153
+
132
154
  queue_task&.stop
133
155
  end
134
156
  end
data/lib/live/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
6
  module Live
7
- VERSION = "0.13.1"
7
+ VERSION = "0.15.0"
8
8
  end
data/lib/live/view.rb CHANGED
@@ -10,11 +10,9 @@ module Live
10
10
  # Represents a single division of content on the page an provides helpers for rendering the content.
11
11
  class View < Element
12
12
  # @returns [Object] The generated HTML.
13
- def to_html
14
- XRB::Builder.fragment do |builder|
15
- builder.inline_tag :div, id: @id, class: "live", data: @data do
16
- render(builder)
17
- end
13
+ def build_markup(builder)
14
+ builder.inline_tag :div, id: @id, class: "live", data: @data do
15
+ render(builder)
18
16
  end
19
17
  end
20
18
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: live
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -39,7 +39,7 @@ cert_chain:
39
39
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
40
40
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
41
41
  -----END CERTIFICATE-----
42
- date: 2024-09-23 00:00:00.000000000 Z
42
+ date: 2024-10-28 00:00:00.000000000 Z
43
43
  dependencies:
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: async-websocket
@@ -55,20 +55,34 @@ dependencies:
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
57
  version: '0.27'
58
+ - !ruby/object:Gem::Dependency
59
+ name: protocol-websocket
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - "~>"
63
+ - !ruby/object:Gem::Version
64
+ version: '0.19'
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '0.19'
58
72
  - !ruby/object:Gem::Dependency
59
73
  name: xrb
60
74
  requirement: !ruby/object:Gem::Requirement
61
75
  requirements:
62
- - - ">="
76
+ - - "~>"
63
77
  - !ruby/object:Gem::Version
64
- version: '0'
78
+ version: '0.10'
65
79
  type: :runtime
66
80
  prerelease: false
67
81
  version_requirements: !ruby/object:Gem::Requirement
68
82
  requirements:
69
- - - ">="
83
+ - - "~>"
70
84
  - !ruby/object:Gem::Version
71
- version: '0'
85
+ version: '0.10'
72
86
  description:
73
87
  email:
74
88
  executables: []
@@ -104,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
118
  - !ruby/object:Gem::Version
105
119
  version: '0'
106
120
  requirements: []
107
- rubygems_version: 3.4.19
121
+ rubygems_version: 3.5.11
108
122
  signing_key:
109
123
  specification_version: 4
110
124
  summary: Live HTML tags updated via a WebSocket.
metadata.gz.sig CHANGED
@@ -1 +1,4 @@
1
- w���L1�dXٔ0c"��c��^9D ���ט ��Vn ��j���Q
1
+ �R�]N"h���w;29�ٮ˺��� � y�V��kTl� �x��X�qz�<QWgf�>:r��a-vr�Ԓ���
2
+ dw����D�����QG� �:O��. �S�~��c���xک'���L�=H�c8"3Z;�k�ޞ���"�t�Y�H���wb�ɵI V��%,vK)(4�aȊ��b3Yy��O�2����C1�љ��?��)A����� ����)��s����|�AF;Ei�
3
+ ����Aq�At�"&Ȍc���U��t���+��W��NeW�s[���"{�[�=
4
+ �� G|@�{�4ަ��֝hq},���nN�A4#5Hn���~1���VJ�ۄ��6.*����L��iM�m ����ѷ��!�'>F��V�R