turbo_cable 1.0.0 → 1.0.2
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
- data/CHANGELOG.md +23 -0
- data/README.md +27 -0
- data/app/helpers/turbo_cable/streams_helper.rb +4 -1
- data/lib/generators/turbo_cable/install/templates/turbo_streams_controller.js +5 -4
- data/lib/turbo_cable/broadcastable.rb +6 -2
- data/lib/turbo_cable/rack_handler.rb +4 -0
- data/lib/turbo_cable/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ff010dd817f03877b7ff08632b9706ec79adb2a2496684421293ff283300c2ae
|
|
4
|
+
data.tar.gz: 2a72051f2ac29891a885c74c0984542a2d2e906cfef54aabbd10f0d737863fc2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bcea8b14d27c9689527d8f8aaa1f27675812a629e866fd68ebd42f7f4961aa81b5176da5d83f24283e515b85aaf02d2b910038f2e23fa9f5e7961e3634c531bb
|
|
7
|
+
data.tar.gz: 949eadd2a6c066fe07b425cb850d5e350b300d6be139995de040b056ee64d5a8a0296222ffbbed52a7f4ed1677425cbab40416046157a3d2c81ac590f74deecc
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.2] - 2025-12-07
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Debug logging throughout the TurboCable pipeline for diagnosing intermittent issues:
|
|
13
|
+
- `turbo_stream_from` helper logs when rendering stream markers
|
|
14
|
+
- `broadcast_json` logs broadcast URL and response codes
|
|
15
|
+
- WebSocket subscription/confirmation logging in RackHandler
|
|
16
|
+
- Broadcast delivery logging with connection count
|
|
17
|
+
|
|
18
|
+
## [1.0.1] - 2025-11-04
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- WebSocket disconnect handling improvements
|
|
23
|
+
- Multi-region deployment support
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Version release checklist in CLAUDE.md
|
|
28
|
+
|
|
8
29
|
## [1.0.0] - 2025-01-04
|
|
9
30
|
|
|
10
31
|
### Added
|
|
@@ -53,4 +74,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
53
74
|
- No bidirectional WebSocket communication (server→client only)
|
|
54
75
|
- No Action Cable channels DSL support
|
|
55
76
|
|
|
77
|
+
[1.0.2]: https://github.com/rubys/turbo_cable/releases/tag/v1.0.2
|
|
78
|
+
[1.0.1]: https://github.com/rubys/turbo_cable/releases/tag/v1.0.1
|
|
56
79
|
[1.0.0]: https://github.com/rubys/turbo_cable/releases/tag/v1.0.0
|
data/README.md
CHANGED
|
@@ -191,6 +191,33 @@ ENV['TURBO_CABLE_BROADCAST_URL'] = 'http://localhost:3000/_broadcast'
|
|
|
191
191
|
- **Thruster/nginx proxy**: When `PORT` is set to the proxy port, not the Rails server port
|
|
192
192
|
- **Never needed**: When `PORT` correctly points to your Rails server (like with Navigator/configurator.rb)
|
|
193
193
|
|
|
194
|
+
### WebSocket URL (Optional)
|
|
195
|
+
|
|
196
|
+
By default, the Stimulus controller connects to `ws://[current-host]/cable`. For custom routing or multi-region deployments, you can specify the WebSocket URL via the standard Rails helper:
|
|
197
|
+
|
|
198
|
+
```erb
|
|
199
|
+
<!-- In your layout -->
|
|
200
|
+
<head>
|
|
201
|
+
<%= action_cable_meta_tag %>
|
|
202
|
+
</head>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
This generates `<meta name="action-cable-url" content="...">` using your configured `config.action_cable.url`.
|
|
206
|
+
|
|
207
|
+
**Example use cases:**
|
|
208
|
+
- **Multi-region deployments**: Route to region-specific endpoints (e.g., `wss://example.com/regions/us-east/cable`)
|
|
209
|
+
- **Reverse proxies**: Use custom paths configured in your proxy (e.g., Navigator, nginx)
|
|
210
|
+
- **Custom routing**: Any non-standard WebSocket endpoint path
|
|
211
|
+
|
|
212
|
+
Configure the URL in your environment config:
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
# config/environments/production.rb
|
|
216
|
+
config.action_cable.url = "wss://example.com/regions/#{ENV['FLY_REGION']}/cable"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The Stimulus controller will use this meta tag if present, otherwise fall back to the default `/cable` endpoint on the current host.
|
|
220
|
+
|
|
194
221
|
## Migration from Action Cable
|
|
195
222
|
|
|
196
223
|
**⚠️ First, verify your deployment architecture supports TurboCable.** If you have multiple Rails instances serving the same app (Heroku dynos, AWS containers, Kubernetes pods, load-balanced VPS), TurboCable won't work for you. See "When NOT to Use" above.
|
|
@@ -3,11 +3,14 @@ module TurboCable
|
|
|
3
3
|
# Custom turbo_stream_from that works with our WebSocket implementation
|
|
4
4
|
# Drop-in replacement for Turbo Stream's turbo_stream_from helper
|
|
5
5
|
def turbo_stream_from(*stream_names)
|
|
6
|
+
streams_str = stream_names.join(",")
|
|
7
|
+
Rails.logger.debug "[TurboCable] turbo_stream_from rendering marker for streams: #{streams_str}"
|
|
8
|
+
|
|
6
9
|
# Create a marker element that JavaScript will find and subscribe to
|
|
7
10
|
tag.div(
|
|
8
11
|
data: {
|
|
9
12
|
turbo_stream: true,
|
|
10
|
-
streams:
|
|
13
|
+
streams: streams_str
|
|
11
14
|
},
|
|
12
15
|
style: "display: none;"
|
|
13
16
|
)
|
|
@@ -30,9 +30,10 @@ export default class extends Controller {
|
|
|
30
30
|
|
|
31
31
|
console.debug("Subscribing to streams:", Array.from(this.streams))
|
|
32
32
|
|
|
33
|
-
// Create WebSocket connection
|
|
34
|
-
const
|
|
35
|
-
|
|
33
|
+
// Create WebSocket connection using the cable URL from meta tag
|
|
34
|
+
const cableUrlMeta = document.querySelector('meta[name="action-cable-url"]')
|
|
35
|
+
const cableUrl = cableUrlMeta?.content || `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}/cable`
|
|
36
|
+
this.ws = new WebSocket(cableUrl)
|
|
36
37
|
this.subscribed = new Set()
|
|
37
38
|
|
|
38
39
|
this.ws.onopen = () => {
|
|
@@ -97,7 +98,7 @@ export default class extends Controller {
|
|
|
97
98
|
})
|
|
98
99
|
this.ws.close()
|
|
99
100
|
}
|
|
100
|
-
this.subscribed
|
|
101
|
+
this.subscribed?.clear()
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
processTurboStream(stream, data) {
|
|
@@ -20,6 +20,8 @@ module TurboCable
|
|
|
20
20
|
default_port = ENV["TURBO_CABLE_PORT"] || ENV["PORT"] || "3000"
|
|
21
21
|
uri = URI(ENV.fetch("TURBO_CABLE_BROADCAST_URL", "http://localhost:#{default_port}/_broadcast"))
|
|
22
22
|
|
|
23
|
+
Rails.logger.debug "[TurboCable] Broadcasting JSON to stream: #{stream_name} via #{uri}" if defined?(Rails)
|
|
24
|
+
|
|
23
25
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
24
26
|
http.open_timeout = 1
|
|
25
27
|
http.read_timeout = 1
|
|
@@ -30,9 +32,11 @@ module TurboCable
|
|
|
30
32
|
data: data
|
|
31
33
|
}.to_json
|
|
32
34
|
|
|
33
|
-
http.request(request)
|
|
35
|
+
response = http.request(request)
|
|
36
|
+
Rails.logger.debug "[TurboCable] Broadcast response: #{response.code}" if defined?(Rails)
|
|
37
|
+
response
|
|
34
38
|
rescue => e
|
|
35
|
-
Rails.logger.error("TurboCable
|
|
39
|
+
Rails.logger.error("[TurboCable] JSON broadcast failed: #{e.class} - #{e.message}") if defined?(Rails)
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
# Async broadcast methods (truly async if Active Job is configured)
|
|
@@ -89,6 +89,7 @@ module TurboCable
|
|
|
89
89
|
case msg["type"]
|
|
90
90
|
when "subscribe"
|
|
91
91
|
stream = msg["stream"]
|
|
92
|
+
Rails.logger.debug "[TurboCable] WebSocket subscribing to stream: #{stream}"
|
|
92
93
|
|
|
93
94
|
# Add connection to stream
|
|
94
95
|
@mutex.synchronize do
|
|
@@ -100,6 +101,7 @@ module TurboCable
|
|
|
100
101
|
# Send confirmation
|
|
101
102
|
response = { type: "subscribed", stream: stream }
|
|
102
103
|
send_frame(io, 1, response.to_json)
|
|
104
|
+
Rails.logger.debug "[TurboCable] WebSocket subscribed confirmation sent for: #{stream}"
|
|
103
105
|
|
|
104
106
|
when "unsubscribe"
|
|
105
107
|
stream = msg["stream"]
|
|
@@ -133,6 +135,8 @@ module TurboCable
|
|
|
133
135
|
# Broadcast to all connections on this stream
|
|
134
136
|
sockets = @mutex.synchronize { @connections[stream]&.dup || [] }
|
|
135
137
|
|
|
138
|
+
Rails.logger.debug "[TurboCable] Broadcasting to stream: #{stream}, #{sockets.size} connection(s)"
|
|
139
|
+
|
|
136
140
|
sockets.each do |io|
|
|
137
141
|
begin
|
|
138
142
|
send_frame(io, 1, payload)
|
data/lib/turbo_cable/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: turbo_cable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Ruby
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-
|
|
10
|
+
date: 2025-12-08 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|