live 0.18.2 → 0.20.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: 6fd073e4bcfdb47b09acbfa2fb6cb1f53b4bc06ecae09ba4854104aa36e9d5f2
4
- data.tar.gz: 68fb08690390f594445794913adbc33e90b5c014f8c4b4efe1fb9614e0461dc9
3
+ metadata.gz: 887023ca9784f151f43b3ac38a1903f2e57a3f1dfac35a661d2ef407e83d42ab
4
+ data.tar.gz: 72556c5d216c93b2be82971ab760d5ea37d581c9c44382d2c2dda5ec69131e82
5
5
  SHA512:
6
- metadata.gz: e8290817ecf9c469d2611a866775dd99386aa79bf00ca8610aae00c754376d2ef950e433dca17c7b5a0aab35530493ed6a18183c402d08901c386a6f098063c2
7
- data.tar.gz: 9699bfdd912686e4d91f189ef0fd103c455dca91e570028d7652614112c6bf4207cbf01c5dd8c8fb0aff4ea2e718f7216a3f7e8702d75a511524c5db86c461ed
6
+ metadata.gz: 369384c0913a6913b60377e227ebefcf41e9175430cea1a4b8153286a0273358501bea9167f5393e2577a0d7526edbb38e9d82ac5f79ee3755e257a0fe78cf89
7
+ data.tar.gz: 746a7bfaee5b317831f9271439b28dd3e8f68de4704c07c363a4766809b734e5881553325c948413c32ee2dc8ffeb13c7ad02cb8bac6976fef7be40fe779c8e9
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/live/element.rb CHANGED
@@ -2,16 +2,20 @@
2
2
 
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2026, by Samuel Williams.
5
+ # Copyright, 2026, by Matt Quinn.
5
6
 
6
7
  require "json"
7
8
  require "securerandom"
8
9
 
9
10
  module Live
11
+ # Raised when an operation requires an element to be bound to a page.
10
12
  class PageError < RuntimeError
11
13
  end
12
14
 
13
15
  # Represents a single dynamic content area on the page.
14
16
  class Element
17
+ # Generate a unique identifier for an element.
18
+ # @returns [String] The generated identifier.
15
19
  def self.unique_id
16
20
  SecureRandom.uuid
17
21
  end
@@ -20,26 +24,36 @@ module Live
20
24
  #
21
25
  # @parameter id [String] The unique identifier within the page.
22
26
  # @parameter data [Hash] The data associated with the element, typically stored as `data-` attributes.
23
- def self.root(id = self.unique_id, **data)
24
- self.new(id, data)
27
+ # @parameter options [Hash] Additional options passed to the element constructor.
28
+ def self.root(id = self.unique_id, data: {}, **options)
29
+ self.new(id, data, **options)
25
30
  end
26
31
 
27
32
  # Mount an element within a parent element.
28
- def self.child(parent, id = self.unique_id, **data)
33
+ # @parameter parent [Element] The parent element.
34
+ # @parameter id [String] The unique identifier within the parent element.
35
+ # @parameter data [Hash] The data associated with the element, typically stored as `data-` attributes.
36
+ # @parameter options [Hash] Additional options passed to the element constructor.
37
+ def self.child(parent, id = self.unique_id, data: {}, **options)
29
38
  full_id = parent.id + ":" + id
30
39
 
31
- self.new(full_id, data)
40
+ self.new(full_id, data, **options)
32
41
  end
33
42
 
34
- def self.mount(parent, id, data = {})
35
- self.child(parent, id, **data)
43
+ # Mount an element within a parent element.
44
+ # @parameter parent [Element] The parent element.
45
+ # @parameter id [String] The unique identifier within the parent element.
46
+ # @parameter data [Hash] The data associated with the element, typically stored as `data-` attributes.
47
+ # @parameter options [Hash] Additional options passed to the element constructor.
48
+ def self.mount(parent, id, data: {}, **options)
49
+ self.child(parent, id, data:, **options)
36
50
  end
37
51
 
38
52
  # Initialize the element with the specified id and data.
39
53
  #
40
54
  # @parameter id [String] The unique identifier within the page.
41
55
  # @parameter data [Hash] The data associated with the element, typically stored as `data-` attributes.
42
- def initialize(id = self.class.unique_id, data = {})
56
+ def initialize(id, data)
43
57
  data[:class] ||= self.class.name
44
58
 
45
59
  @id = id
@@ -53,7 +67,7 @@ module Live
53
67
  # The data associated with the element.
54
68
  attr :data
55
69
 
56
- # @attribute [Page | Nil] The page this elemenet is bound to.
70
+ # @attribute [Page | Nil] The page this element is bound to.
57
71
  attr :page
58
72
 
59
73
  # Generate a JavaScript string which forwards the specified event to the server.
@@ -66,6 +80,9 @@ module Live
66
80
  end
67
81
  end
68
82
 
83
+ # Generate JavaScript which forwards a form event and its form data to the server.
84
+ # @parameter detail [Hash | Nil] Additional detail associated with the forwarded event.
85
+ # @returns [String] The generated JavaScript expression.
69
86
  def forward_form_event(detail = nil)
70
87
  if detail
71
88
  "live.forwardFormEvent(#{JSON.dump(@id)}, event, #{JSON.dump(detail)})"
@@ -80,17 +97,18 @@ module Live
80
97
  @page = page
81
98
  end
82
99
 
100
+ # Detach the element from its page.
83
101
  def close
84
102
  @page = nil
85
103
  end
86
104
 
87
- # Handle a client event, typically as triggered by {#forward}.
105
+ # Handle a client event, typically as triggered by {#forward_event}.
88
106
  # @parameter event [String] The type of the event.
89
107
  def handle(event)
90
108
  end
91
109
 
92
110
  # Enqueue a remote procedure call to the currently bound page.
93
- # @parameter method [Symbol] The name of the remote functio to invoke.
111
+ # @parameter method [Symbol] The name of the remote function to invoke.
94
112
  # @parameter arguments [Array]
95
113
  def rpc(*arguments)
96
114
  if @page
@@ -102,6 +120,9 @@ module Live
102
120
  end
103
121
  end
104
122
 
123
+ # Execute JavaScript in the context of the client-side element.
124
+ # @parameter code [String] The JavaScript source code to execute.
125
+ # @parameter options [Hash] Options for the remote procedure call.
105
126
  def script(code, **options)
106
127
  rpc(:script, @id, code, options)
107
128
  end
@@ -144,6 +165,10 @@ module Live
144
165
  rpc(:remove, selector, options)
145
166
  end
146
167
 
168
+ # Dispatch an event to each client-side element matching the selector.
169
+ # @parameter selector [String] The CSS selector for the target elements.
170
+ # @parameter type [String] The event type to dispatch.
171
+ # @parameter options [Hash] The event initialization options.
147
172
  def dispatch_event(selector, type, **options)
148
173
  rpc(:dispatchEvent, selector, type, options)
149
174
  end
@@ -154,10 +179,14 @@ module Live
154
179
  builder.text(self.class.name)
155
180
  end
156
181
 
182
+ # Append this element's markup to the specified output buffer.
183
+ # @parameter output [Object] The output buffer which receives the markup.
157
184
  def append_markup(output)
158
185
  build_markup(::XRB::Builder.new(output))
159
186
  end
160
187
 
188
+ # Build this element's markup with the specified builder.
189
+ # @parameter builder [XRB::Builder] The builder which receives the markup.
161
190
  def build_markup(builder)
162
191
  render(builder)
163
192
  end
data/lib/live/page.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2021-2024, by Samuel Williams.
4
+ # Copyright, 2021-2026, by Samuel Williams.
5
5
 
6
6
  require_relative "element"
7
7
  require_relative "resolver"
@@ -41,6 +41,8 @@ module Live
41
41
  @attached[element.id] = element
42
42
  end
43
43
 
44
+ # Detach and close a previously attached element.
45
+ # @parameter element [Live::Element] The element to detach.
44
46
  def detach(element)
45
47
  if @attached.delete(element.id)
46
48
  element.close
@@ -71,6 +73,7 @@ module Live
71
73
  return nil
72
74
  end
73
75
 
76
+ # Close all elements bound to the page.
74
77
  def close
75
78
  @elements.each do |id, element|
76
79
  begin
@@ -81,6 +84,8 @@ module Live
81
84
  end
82
85
  end
83
86
 
87
+ # Enqueue an update to be sent to the connected client.
88
+ # @parameter update [Array] The remote procedure call to serialize and send.
84
89
  def enqueue(update)
85
90
  @updates.enqueue(::Protocol::WebSocket::TextMessage.generate(update))
86
91
  end
data/lib/live/resolver.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2021-2024, by Samuel Williams.
4
+ # Copyright, 2021-2026, by Samuel Williams.
5
5
 
6
6
  require_relative "element"
7
7
 
@@ -13,6 +13,7 @@ module Live
13
13
  self.new.allow(*arguments).freeze
14
14
  end
15
15
 
16
+ # Initialize an empty resolver.
16
17
  def initialize
17
18
  @allowed = {}
18
19
  end
@@ -20,6 +21,7 @@ module Live
20
21
  # @attribute [Hash(String, Class)] A map of allowed class names.
21
22
  attr :allowed
22
23
 
24
+ # Freeze the resolver and its map of allowed classes.
23
25
  def freeze
24
26
  return self unless frozen?
25
27
 
@@ -37,14 +39,35 @@ module Live
37
39
  return self
38
40
  end
39
41
 
42
+ # Construct an allowed root element from its class.
43
+ # @parameter view_class [Class] The view class to construct.
44
+ # @parameter id [String] The unique identifier for the view.
45
+ # @parameter data [Hash] The data associated with the view.
46
+ # @parameter options [Hash] Additional options passed to the view constructor.
47
+ # @returns [Element] A new view instance.
48
+ # @raises [ArgumentError] If the view class is not allowed.
49
+ def root(view_class, id = view_class.unique_id, data: {}, **options)
50
+ unless @allowed[view_class.name].equal?(view_class)
51
+ raise ArgumentError, "View class is not allowed: #{view_class.to_s.dump}!"
52
+ end
53
+
54
+ return make(view_class, id, data, **options)
55
+ end
56
+
40
57
  # Resolve a tag.
41
58
  # @parameter id [String] The unique identifier for the tag.
42
59
  # @parameter data [Hash] The data associated with the tag. Should include the `:class` key.
43
60
  # @returns [Element] The element instance if it was allowed.
44
61
  def call(id, data)
45
- if klass = @allowed[data[:class]]
46
- return klass.new(id, data)
62
+ if view_class = @allowed[data[:class]]
63
+ return make(view_class, id, data)
47
64
  end
48
65
  end
66
+
67
+ private
68
+
69
+ def make(view_class, id, data, **options)
70
+ view_class.new(id, data, **options)
71
+ end
49
72
  end
50
73
  end
data/lib/live/version.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2026, by Samuel Williams.
5
5
 
6
+ # @namespace
6
7
  module Live
7
- VERSION = "0.18.2"
8
+ VERSION = "0.20.0"
8
9
  end
data/lib/live/view.rb CHANGED
@@ -7,8 +7,10 @@ require_relative "element"
7
7
  require "xrb/builder"
8
8
 
9
9
  module Live
10
- # Represents a single division of content on the page an provides helpers for rendering the content.
10
+ # Represents a single division of content on the page and provides helpers for rendering the content.
11
11
  class View < Element
12
+ # Get the custom element tag name used to render the view.
13
+ # @returns [String] The custom element tag name.
12
14
  def tag_name
13
15
  "live-view"
14
16
  end
data/license.md CHANGED
@@ -3,6 +3,7 @@
3
3
  Copyright, 2021-2026, by Samuel Williams.
4
4
  Copyright, 2023, by Olle Jonsson.
5
5
  Copyright, 2024, by Tatsuhiro Ujihisa.
6
+ Copyright, 2026, by Matt Quinn.
6
7
 
7
8
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
9
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Live
2
2
 
3
- Provides bi-directional live HTML views using WebSockets for communication. You can try out a [live example](https://utopia-falcon-heroku.herokuapp.com/live/index)
3
+ Provides bi-directional live HTML views using WebSockets for communication.
4
4
 
5
5
  [![Development Status](https://github.com/socketry/live/workflows/Test/badge.svg)](https://github.com/socketry/live/actions?workflow=Test)
6
6
 
@@ -18,27 +18,17 @@ Please see the [project documentation](https://socketry.github.io/live/) for mor
18
18
 
19
19
  - [Rails Integration](https://socketry.github.io/live/guides/rails-integration/index) - This guide explains how to use the `live` gem with Ruby on Rails.
20
20
 
21
- ## Contributing
22
-
23
- We welcome contributions to this project.
24
-
25
- 1. Fork it.
26
- 2. Create your feature branch (`git checkout -b my-new-feature`).
27
- 3. Commit your changes (`git commit -am 'Add some feature'`).
28
- 4. Push to the branch (`git push origin my-new-feature`).
29
- 5. Create new Pull Request.
21
+ ## Releases
30
22
 
31
- ### Running Tests
23
+ Please see the [project releases](https://socketry.github.io/live/releases/index) for all releases.
32
24
 
33
- To run the test suite:
25
+ ### v0.20.0
34
26
 
35
- ``` shell
36
- bundle exec sus
37
- ```
27
+ - [Web Packages](https://socketry.github.io/live/releases/index#web-packages)
38
28
 
39
- ### Making Releases
29
+ ### v0.19.0
40
30
 
41
- Please see the [project releases](https://socketry.github.io/live/releases/index) for all releases.
31
+ - [Explicit Element Construction](https://socketry.github.io/live/releases/index#explicit-element-construction)
42
32
 
43
33
  ### v0.18.0
44
34
 
@@ -47,45 +37,46 @@ Please see the [project releases](https://socketry.github.io/live/releases/index
47
37
  - Using older versions of `live` with `live-js` v0.16.0 or later may also result in unexpected behavior or errors.
48
38
  - Updating both `live` and `live-js` to their latest versions is recommended to ensure compatibility, and requires no changes to application code.
49
39
 
50
- ### v0.18.0
40
+ ## See Also
51
41
 
52
- - **Breaking Change**: Live now uses Web Components for managing life-cycle events instead of observers. You will need to use `live-js` v0.16.0 or later with this version of `live`, which emits `<live-view>` elements (instead of `<div>` elements).
53
- - Using older versions of `live-js` with this version of `live` may result in unexpected behavior or errors.
54
- - Using older versions of `live` with `live-js` v0.16.0 or later may also result in unexpected behavior or errors.
55
- - Updating both `live` and `live-js` to their latest versions is recommended to ensure compatibility, and requires no changes to application code.
42
+ - [live-js](https://github.com/socketry/live-js) The client-side JavaScript library.
43
+ - [morphdom](https://github.com/patrick-steele-idem/morphdom) Efficiently update the client-side HTML.
44
+ - [stimulus-reflex](https://github.com/hopsoft/stimulus_reflex) An alternative framework which provides similar functionality.
56
45
 
57
- ### v0.18.0
46
+ ### Examples
58
47
 
59
- - **Breaking Change**: Live now uses Web Components for managing life-cycle events instead of observers. You will need to use `live-js` v0.16.0 or later with this version of `live`, which emits `<live-view>` elements (instead of `<div>` elements).
60
- - Using older versions of `live-js` with this version of `live` may result in unexpected behavior or errors.
61
- - Using older versions of `live` with `live-js` v0.16.0 or later may also result in unexpected behavior or errors.
62
- - Updating both `live` and `live-js` to their latest versions is recommended to ensure compatibility, and requires no changes to application code.
48
+ - [Flappy Bird](https://github.com/socketry/flappy-bird) A clone of the classic Flappy Bird game.
63
49
 
64
- ### Developer Certificate of Origin
50
+ ## Contributing
65
51
 
66
- In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
52
+ We welcome contributions to this project.
67
53
 
68
- ### Community Guidelines
54
+ 1. Fork the repository.
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
56
+ 3. Commit your changes (`git commit -am 'Add some feature.'`).
57
+ 4. Push to the branch (`git push origin my-new-feature`).
58
+ 5. Create a new pull request.
69
59
 
70
- This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
60
+ ### Running Tests
71
61
 
72
- ## Releases
62
+ To run the test suite:
73
63
 
74
- Please see the [project releases](https://socketry.github.io/live/releases/index) for all releases.
64
+ ``` bash
65
+ $ bundle exec sus
66
+ ```
75
67
 
76
- ### v0.18.0
68
+ ### Making Releases
77
69
 
78
- - **Breaking Change**: Live now uses Web Components for managing life-cycle events instead of observers. You will need to use `live-js` v0.16.0 or later with this version of `live`, which emits `<live-view>` elements (instead of `<div>` elements).
79
- - Using older versions of `live-js` with this version of `live` may result in unexpected behavior or errors.
80
- - Using older versions of `live` with `live-js` v0.16.0 or later may also result in unexpected behavior or errors.
81
- - Updating both `live` and `live-js` to their latest versions is recommended to ensure compatibility, and requires no changes to application code.
70
+ To make a new release:
82
71
 
83
- ## See Also
72
+ ``` bash
73
+ $ bundle exec bake gem:release:patch # or minor or major
74
+ ```
84
75
 
85
- - [live-js](https://github.com/socketry/live-js) The client-side JavaScript library.
86
- - [morphdom](https://github.com/patrick-steele-idem/morphdom) – Efficiently update the client-side HTML.
87
- - [stimulus-reflex](https://github.com/hopsoft/stimulus_reflex) — An alternative framework which provides similar functionality.
76
+ ### Developer Certificate of Origin
88
77
 
89
- ### Examples
78
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
90
79
 
91
- - [Flappy Bird](https://github.com/socketry/flappy-bird) – A clone of the classic Flappy Bird game.
80
+ ### Community Guidelines
81
+
82
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data/releases.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Releases
2
2
 
3
+ ## v0.20.0
4
+
5
+ ### Web Packages
6
+
7
+ Live now uses `web-packages` to install and project the JavaScript packages used by its browser integration tests. The generated static package manifest supplies the test page import map, while `node_modules` is treated as a disposable package-manager projection.
8
+
9
+ ## v0.19.0
10
+
11
+ ### Explicit Element Construction
12
+
13
+ Element construction now separates serialized element data from Ruby constructor options and makes the intended construction path explicit.
14
+
15
+ - `Live::Element#initialize` now requires both `id` and `data`. Replace `MyView.new` with `MyView.root`, and replace `MyView.new("custom-id")` with `MyView.root("custom-id")`. Internal callers using `new` directly must pass the data hash explicitly, even when empty.
16
+ - `Live::Element.root`, `.child`, and `.mount` now accept serialized attributes through `data:`. Other keyword arguments are forwarded to `initialize`. For example, change `MyView.root(mode: "presenter")` to `MyView.root(data: {mode: "presenter"})`; constructor dependencies such as `controller:` can remain ordinary keyword arguments.
17
+ - Calls passing a positional data hash to `.mount` must use the `data:` keyword. Change `ChildView.mount(parent, "child", {mode: "compact"})` to `ChildView.mount(parent, "child", data: {mode: "compact"})`.
18
+ - `Live::Resolver#root(view_class, id = view_class.unique_id, data: {}, **options)` constructs an allowed root using the same internal path as browser-resolved elements. Custom resolvers that inject dependencies can override the private `make(view_class, id, data, **options)` method instead of overriding `call`.
19
+
3
20
  ## v0.18.0
4
21
 
5
22
  - **Breaking Change**: Live now uses Web Components for managing life-cycle events instead of observers. You will need to use `live-js` v0.16.0 or later with this version of `live`, which emits `<live-view>` elements (instead of `<div>` elements).
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,10 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: live
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.2
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
+ - Matt Quinn
8
9
  - Olle Jonsson
9
10
  - Tatsuhiro Ujihisa
10
11
  bindir: bin
@@ -99,6 +100,8 @@ homepage: https://github.com/socketry/live
99
100
  licenses:
100
101
  - MIT
101
102
  metadata:
103
+ bug_tracker_uri: https://github.com/socketry/live/issues
104
+ changelog_uri: https://github.com/socketry/live/blob/main/releases.md
102
105
  documentation_uri: https://socketry.github.io/live/
103
106
  source_code_uri: https://github.com/socketry/live.git
104
107
  rdoc_options: []
@@ -115,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
118
  - !ruby/object:Gem::Version
116
119
  version: '0'
117
120
  requirements: []
118
- rubygems_version: 4.0.6
121
+ rubygems_version: 4.0.10
119
122
  specification_version: 4
120
123
  summary: Live HTML tags updated via a WebSocket.
121
124
  test_files: []
metadata.gz.sig CHANGED
Binary file