live 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7df6409f470eb90e1f1f68cd70dabcf23cf56c2cbcbcc5707222bcac7d721338
4
- data.tar.gz: faac890736a9dc375e683405d29c534a55b7628e37abbcd64cfae0922ebdeda8
3
+ metadata.gz: 01e0a2e5881cd9cb589f93184b159a022a884a3b6549d6da54764ebe05bd8b81
4
+ data.tar.gz: 3cc1bd067307955f663cd9318bf60ec80dce9a4759df0935d3b00176c0183c85
5
5
  SHA512:
6
- metadata.gz: d1f0603af15f67f6db3677126f45f1c766bccecf99d93aaae0fc9018c0da5deaaa5f0156fe187ea9d90cac5bf813540de62e084c840bbe28eedfdc18a69fe4af
7
- data.tar.gz: 5db6880399468684e09034225faa3a63929563177d28b32ae67bbe9022158d15b98fc2ba0a967c6bd88177cb1b9518b85a45caeb3ef07309f446fe2b2b639862
6
+ metadata.gz: b74fd0f4365c5eb0fcf8ed1b8064ad5efd39ebcd56a12b4cb9e144a6dce0a503eb14f054fb16332b20abe905c364b36486b594ab9f4992fb645d41fff860be21
7
+ data.tar.gz: 80a79b3466c52e0cc0989416c547c06e39d9059a910489a16c713ab046a83480b10c645e33420fc31fa262894c02d9bcef01a7c9e3fe17e86f571524bc1eb519
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/live/element.rb CHANGED
@@ -4,13 +4,18 @@
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
6
  require 'json'
7
+ require 'securerandom'
7
8
 
8
9
  module Live
9
10
  # Represents a single dynamic content area on the page.
10
11
  class Element
12
+ def self.unique_id
13
+ SecureRandom.uuid
14
+ end
15
+
11
16
  # @parameter id [String] The unique identifier within the page.
12
17
  # @parameter data [Hash] The data associated with the element, typically stored as `data-` attributes.
13
- def initialize(id, **data)
18
+ def initialize(id = Element.unique_id, **data)
14
19
  @id = id
15
20
  @data = data
16
21
  @data[:class] ||= self.class.name
@@ -21,13 +26,24 @@ module Live
21
26
  # The unique id within the bound page.
22
27
  attr :id
23
28
 
29
+ # The data associated with the element.
30
+ attr :data
31
+
24
32
  # Generate a JavaScript string which forwards the specified event to the server.
25
- # @parameter details [Hash] The details associated with the forwarded event.
26
- def forward(details = nil)
27
- if details
28
- "live.forward(#{JSON.dump(@id)}, event, #{JSON.dump(details)})"
33
+ # @parameter detail [Hash] The detail associated with the forwarded event.
34
+ def forward_event(detail = nil)
35
+ if detail
36
+ "live.forwardEvent(#{JSON.dump(@id)}, event, #{JSON.dump(detail)})"
37
+ else
38
+ "live.forwardEvent(#{JSON.dump(@id)}, event)"
39
+ end
40
+ end
41
+
42
+ def forward_form_event(detail = nil)
43
+ if detail
44
+ "live.forwardFormEvent(#{JSON.dump(@id)}, event, #{JSON.dump(detail)})"
29
45
  else
30
- "live.forward(#{JSON.dump(@id)}, event)"
46
+ "live.forwardFormEvent(#{JSON.dump(@id)}, event)"
31
47
  end
32
48
  end
33
49
 
@@ -49,9 +65,9 @@ module Live
49
65
  # Enqueue a remote procedure call to the currently bound page.
50
66
  # @parameter method [Symbol] The name of the remote functio to invoke.
51
67
  # @parameter arguments [Array]
52
- def rpc(method, arguments)
68
+ def rpc(*arguments)
53
69
  # 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:
54
- @page.updates.enqueue([method, arguments])
70
+ @page.updates.enqueue(arguments)
55
71
  end
56
72
  end
57
73
  end
data/lib/live/page.rb CHANGED
@@ -43,14 +43,13 @@ module Live
43
43
  # Handle an event from the client. If the element could not be found, it is silently ignored.
44
44
  # @parameter id [String] The unique identifier of the element which forwarded the event.
45
45
  # @parameter event [String] The type of the event.
46
- # @parameter details [Hash] The associated details if any.
47
46
  # @returns [Object] The result of the element handler, if the element was found.
48
47
  # @returns [Nil] If the element could not be found.
49
48
  def handle(id, event)
50
49
  if element = @elements[id]
51
50
  return element.handle(event)
52
51
  else
53
- Console.logger.warn(self, "Could not handle event:", event, details)
52
+ Console.warn(self, "Could not handle event:", id:, event:)
54
53
  end
55
54
 
56
55
  return nil
@@ -64,16 +63,28 @@ module Live
64
63
 
65
64
  # Process a single incoming message from the network.
66
65
  def process_message(message)
67
- if id = message[:bind] and data = message[:data]
68
- if element = self.resolve(id, data)
66
+ case message[0]
67
+ when 'bind'
68
+ # Bind a client-side element to a server-side element.
69
+ if element = self.resolve(message[1], message[2])
69
70
  self.bind(element)
70
71
  else
71
- Console.logger.warn(self, "Could not resolve element:", message)
72
+ Console.warn(self, "Could not resolve element:", message)
73
+ # @updates.enqueue(['error', message[1], "Could not resolve element!"])
72
74
  end
73
- elsif id = message[:id]
74
- self.handle(id, message[:event])
75
+ when 'unbind'
76
+ # Unbind a client-side element from a server-side element.
77
+ if element = @elements.delete(message[1])
78
+ element.close
79
+ else
80
+ Console.warn(self, "Could not unbind element:", message)
81
+ @updates.enqueue(['error', message[1], "Could not unbind element!"])
82
+ end
83
+ when 'event'
84
+ # Handle an event from the client.
85
+ self.handle(message[1], message[2])
75
86
  else
76
- Console.logger.warn(self, "Unhandled message:", message)
87
+ Console.warn(self, "Unhandled message:", message)
77
88
  end
78
89
  end
79
90
 
@@ -82,7 +93,7 @@ module Live
82
93
  def run(connection)
83
94
  queue_task = Async do
84
95
  while update = @updates.dequeue
85
- Console.logger.debug(self, "Sending update:", update)
96
+ Console.debug(self, "Sending update:", update)
86
97
 
87
98
  connection.write(::Protocol::WebSocket::JSONMessage.generate(update))
88
99
  connection.flush if @updates.empty?
@@ -90,12 +101,12 @@ module Live
90
101
  end
91
102
 
92
103
  while message = connection.read
93
- Console.logger.debug(self, "Reading message:", message)
104
+ Console.debug(self, "Reading message:", message)
94
105
 
95
106
  if json_message = ::Protocol::WebSocket::JSONMessage.wrap(message)
96
107
  process_message(json_message.parse)
97
108
  else
98
- Console.logger.warn(self, "Unhandled message:", message)
109
+ Console.warn(self, "Unhandled message:", message)
99
110
  end
100
111
  end
101
112
  ensure
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.6.0"
7
+ VERSION = "0.8.0"
8
8
  end
data/lib/live/view.rb CHANGED
@@ -9,21 +9,40 @@ require 'xrb/builder'
9
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
+ # Update the content of the client-side element by rendering this view.
13
+ def update!(**options)
14
+ rpc(:update, @id, self.to_html, options)
15
+ end
16
+
12
17
  # Replace the content of the client-side element by rendering this view.
13
- def replace!
14
- rpc(:replace, [@id, self.to_html])
18
+ # @parameter selector [String] The CSS selector to replace.
19
+ # @parameter node [String] The HTML to replace.
20
+ def replace(selector, node, **options)
21
+ rpc(:replace, selector, node.to_s, options)
22
+ end
23
+
24
+ # Prepend to the content of the client-side element by appending the specified element.
25
+ # @parameter selector [String] The CSS selector to prepend to.
26
+ # @parameter node [String] The HTML to prepend.
27
+ def prepend(selector, node, **options)
28
+ rpc(:prepend, selector, node.to_s, options)
15
29
  end
16
30
 
17
31
  # Append to the content of the client-side element by appending the specified element.
18
- # @parameter node [Live::Element] The element to append.
19
- def append!(element)
20
- rpc(:append, [@id, element.to_html])
32
+ # @parameter selector [String] The CSS selector to append to.
33
+ # @parameter node [String] The HTML to prepend.
34
+ def append(selector, node, **options)
35
+ rpc(:append, selector, node.to_s, options)
21
36
  end
22
37
 
23
- # Prepend to the content of the client-side element by appending the specified element.
24
- # @parameter node [Live::Element] The element to prepend.
25
- def prepend!(element)
26
- rpc(:prepend, [@id, element.to_html])
38
+ # Remove the specified element from the client-side element.
39
+ # @parameter selector [String] The CSS selector to remove.
40
+ def remove(selector, **options)
41
+ rpc(:remove, selector, options)
42
+ end
43
+
44
+ def dispatch_event(selector, type, **options)
45
+ rpc(:dispatch_event, selector, event, options)
27
46
  end
28
47
 
29
48
  # Render the element.
data/lib/live.rb CHANGED
@@ -7,4 +7,4 @@ require_relative "live/version"
7
7
 
8
8
  require_relative 'live/page'
9
9
  require_relative 'live/view'
10
-
10
+ require_relative 'live/resolver'
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.6.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -38,7 +38,7 @@ cert_chain:
38
38
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
39
39
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
40
40
  -----END CERTIFICATE-----
41
- date: 2024-04-28 00:00:00.000000000 Z
41
+ date: 2024-05-05 00:00:00.000000000 Z
42
42
  dependencies:
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: async-websocket
metadata.gz.sig CHANGED
Binary file