live 0.13.0 → 0.14.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/live/element.rb +3 -3
- data/lib/live/page.rb +48 -20
- data/lib/live/resolver.rb +1 -1
- data/lib/live/version.rb +1 -1
- data/lib/live/view.rb +3 -3
- data/lib/live.rb +3 -3
- data.tar.gz.sig +0 -0
- metadata +16 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63034baadcba271590245009b106e82bc142734cbc4978d7a47c264a8368d92c
|
4
|
+
data.tar.gz: ddb382c9499a3560ece8341a61e6d78076b2b2544fbb7ff3de1371e315e321bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8c7edabe0b494d83b0260e803cf39899eb4a2bd91a8eba9e714ccf255f23cd7bb76ee19df9811bc255f316cc113c67fa9814b0152fcd0d05382e3c5e8f93877
|
7
|
+
data.tar.gz: d4e8a3bfebf1bd77374cba4bac80d428b218834c2f0acb773268093aeb14ea14f3131194533c7a8aa0094431d20ee224f584d4babe6c27d9e7852119223cb578
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/live/element.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2021-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "json"
|
7
|
+
require "securerandom"
|
8
8
|
|
9
9
|
module Live
|
10
10
|
class PageError < RuntimeError
|
@@ -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.
|
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!"
|
data/lib/live/page.rb
CHANGED
@@ -3,14 +3,16 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2021-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
6
|
+
require_relative "element"
|
7
|
+
require_relative "resolver"
|
8
8
|
|
9
|
-
require
|
10
|
-
require
|
9
|
+
require "async"
|
10
|
+
require "async/queue"
|
11
11
|
|
12
|
-
require
|
13
|
-
require
|
12
|
+
require "protocol/websocket"
|
13
|
+
require "protocol/websocket/message"
|
14
|
+
|
15
|
+
require "console/event/failure"
|
14
16
|
|
15
17
|
module Live
|
16
18
|
# Represents a connected client page with bound dynamic content areas.
|
@@ -25,9 +27,6 @@ module Live
|
|
25
27
|
@updates = Async::Queue.new
|
26
28
|
end
|
27
29
|
|
28
|
-
# The queue of outstanding events to be sent to the client.
|
29
|
-
attr :updates
|
30
|
-
|
31
30
|
# Bind a client-side element to a server side element.
|
32
31
|
# @parameter element [Live::Element] The element to bind.
|
33
32
|
def bind(element)
|
@@ -74,30 +73,38 @@ module Live
|
|
74
73
|
|
75
74
|
def close
|
76
75
|
@elements.each do |id, element|
|
77
|
-
|
76
|
+
begin
|
77
|
+
element.close
|
78
|
+
rescue => error
|
79
|
+
Console::Event::Failure.for(error).emit(self)
|
80
|
+
end
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
84
|
+
def enqueue(update)
|
85
|
+
@updates.enqueue(::Protocol::WebSocket::TextMessage.generate(update))
|
86
|
+
end
|
87
|
+
|
81
88
|
# Process a single incoming message from the network.
|
82
89
|
def process_message(message)
|
83
90
|
case message[0]
|
84
|
-
when
|
91
|
+
when "bind"
|
85
92
|
# Bind a client-side element to a server-side element.
|
86
93
|
if element = self.resolve(message[1], message[2])
|
87
94
|
self.bind(element)
|
88
95
|
else
|
89
96
|
Console.warn(self, "Could not resolve element:", message)
|
90
|
-
|
97
|
+
self.enqueue(["error", message[1], "Could not resolve element!"])
|
91
98
|
end
|
92
|
-
when
|
99
|
+
when "unbind"
|
93
100
|
# Unbind a client-side element from a server-side element.
|
94
101
|
if element = @elements.delete(message[1])
|
95
102
|
element.close unless @attached.key?(message[1])
|
96
103
|
else
|
97
104
|
Console.warn(self, "Could not unbind element:", message)
|
98
|
-
|
105
|
+
self.enqueue(["error", message[1], "Could not unbind element!"])
|
99
106
|
end
|
100
|
-
when
|
107
|
+
when "event"
|
101
108
|
# Handle an event from the client.
|
102
109
|
self.handle(message[1], message[2])
|
103
110
|
else
|
@@ -107,22 +114,43 @@ module Live
|
|
107
114
|
|
108
115
|
# Run the event handling loop with the given websocket connection.
|
109
116
|
# @parameter connection [Async::WebSocket::Connection]
|
110
|
-
def run(connection)
|
117
|
+
def run(connection, keep_alive: 10)
|
111
118
|
Sync do |task|
|
119
|
+
last_update = Async::Clock.now
|
120
|
+
|
112
121
|
queue_task = task.async do
|
113
122
|
while update = @updates.dequeue
|
114
|
-
|
115
|
-
|
116
|
-
|
123
|
+
update.send(connection)
|
124
|
+
|
125
|
+
# Flush the output if there are no more updates:
|
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
|
117
142
|
end
|
118
143
|
end
|
119
144
|
|
120
145
|
while message = connection.read
|
121
|
-
|
146
|
+
last_update = Async::Clock.now
|
122
147
|
process_message(message.parse)
|
123
148
|
end
|
124
149
|
ensure
|
150
|
+
keep_alive_task&.stop
|
151
|
+
|
125
152
|
self.close
|
153
|
+
|
126
154
|
queue_task&.stop
|
127
155
|
end
|
128
156
|
end
|
data/lib/live/resolver.rb
CHANGED
data/lib/live/version.rb
CHANGED
data/lib/live/view.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2021-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require
|
6
|
+
require_relative "element"
|
7
|
+
require "xrb/builder"
|
8
8
|
|
9
9
|
module Live
|
10
10
|
# Represents a single division of content on the page an provides helpers for rendering the content.
|
@@ -12,7 +12,7 @@ module Live
|
|
12
12
|
# @returns [Object] The generated HTML.
|
13
13
|
def to_html
|
14
14
|
XRB::Builder.fragment do |builder|
|
15
|
-
builder.inline_tag :div, id: @id, class:
|
15
|
+
builder.inline_tag :div, id: @id, class: "live", data: @data do
|
16
16
|
render(builder)
|
17
17
|
end
|
18
18
|
end
|
data/lib/live.rb
CHANGED
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.
|
4
|
+
version: 0.14.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-
|
42
|
+
date: 2024-09-25 00:00:00.000000000 Z
|
43
43
|
dependencies:
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
45
|
name: async-websocket
|
@@ -55,6 +55,20 @@ 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
|
metadata.gz.sig
CHANGED
Binary file
|