live 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|