turbo-rails 1.5.0 → 2.0.11
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/README.md +126 -16
- data/app/assets/javascripts/turbo.js +2226 -953
- data/app/assets/javascripts/turbo.min.js +9 -5
- data/app/assets/javascripts/turbo.min.js.map +1 -1
- data/app/channels/turbo/streams/broadcasts.rb +47 -10
- data/app/channels/turbo/streams_channel.rb +15 -15
- data/app/controllers/concerns/turbo/request_id_tracking.rb +12 -0
- data/app/controllers/turbo/frames/frame_request.rb +2 -2
- data/app/controllers/turbo/native/navigation.rb +17 -11
- data/app/helpers/turbo/drive_helper.rb +72 -14
- data/app/helpers/turbo/frames_helper.rb +8 -8
- data/app/helpers/turbo/streams/action_helper.rb +12 -4
- data/app/helpers/turbo/streams_helper.rb +5 -0
- data/app/javascript/turbo/cable_stream_source_element.js +10 -0
- data/app/javascript/turbo/index.js +2 -0
- data/app/jobs/turbo/streams/action_broadcast_job.rb +2 -2
- data/app/jobs/turbo/streams/broadcast_job.rb +1 -1
- data/app/jobs/turbo/streams/broadcast_stream_job.rb +7 -0
- data/app/models/concerns/turbo/broadcastable.rb +201 -42
- data/app/models/turbo/debouncer.rb +24 -0
- data/app/models/turbo/streams/tag_builder.rb +50 -12
- data/app/models/turbo/thread_debouncer.rb +28 -0
- data/config/routes.rb +3 -4
- data/lib/install/turbo_with_importmap.rb +1 -1
- data/lib/tasks/turbo_tasks.rake +0 -22
- data/lib/turbo/broadcastable/test_helper.rb +5 -5
- data/lib/turbo/engine.rb +80 -9
- data/lib/turbo/system_test_helper.rb +128 -0
- data/lib/turbo/test_assertions/integration_test_assertions.rb +2 -2
- data/lib/turbo/test_assertions.rb +2 -2
- data/lib/turbo/version.rb +1 -1
- data/lib/turbo-rails.rb +10 -0
- metadata +10 -19
- data/lib/install/turbo_needs_redis.rb +0 -20
data/lib/tasks/turbo_tasks.rake
CHANGED
@@ -5,20 +5,6 @@ module Turbo
|
|
5
5
|
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/#{path}.rb", __dir__)}"
|
6
6
|
end
|
7
7
|
|
8
|
-
def redis_installed?
|
9
|
-
Gem.win_platform? ?
|
10
|
-
system('where redis-server > NUL 2>&1') :
|
11
|
-
system('which redis-server > /dev/null')
|
12
|
-
end
|
13
|
-
|
14
|
-
def switch_on_redis_if_available
|
15
|
-
if redis_installed?
|
16
|
-
Rake::Task["turbo:install:redis"].invoke
|
17
|
-
else
|
18
|
-
puts "Run turbo:install:redis to switch on Redis and use it in development for turbo streams"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
8
|
def using_bun?
|
23
9
|
Rails.root.join("bun.config.js").exist?
|
24
10
|
end
|
@@ -43,24 +29,16 @@ namespace :turbo do
|
|
43
29
|
desc "Install Turbo into the app with asset pipeline"
|
44
30
|
task :importmap do
|
45
31
|
Turbo::Tasks.run_turbo_install_template "turbo_with_importmap"
|
46
|
-
Turbo::Tasks.switch_on_redis_if_available
|
47
32
|
end
|
48
33
|
|
49
34
|
desc "Install Turbo into the app with webpacker"
|
50
35
|
task :node do
|
51
36
|
Turbo::Tasks.run_turbo_install_template "turbo_with_node"
|
52
|
-
Turbo::Tasks.switch_on_redis_if_available
|
53
37
|
end
|
54
38
|
|
55
39
|
desc "Install Turbo into the app with bun"
|
56
40
|
task :bun do
|
57
41
|
Turbo::Tasks.run_turbo_install_template "turbo_with_bun"
|
58
|
-
Turbo::Tasks.switch_on_redis_if_available
|
59
|
-
end
|
60
|
-
|
61
|
-
desc "Switch on Redis and use it in development"
|
62
|
-
task :redis do
|
63
|
-
Turbo::Tasks.run_turbo_install_template "turbo_needs_redis"
|
64
42
|
end
|
65
43
|
end
|
66
44
|
end
|
@@ -11,14 +11,14 @@ module Turbo
|
|
11
11
|
|
12
12
|
# Asserts that `<turbo-stream>` elements were broadcast over Action Cable
|
13
13
|
#
|
14
|
-
#
|
14
|
+
# ==== Arguments
|
15
15
|
#
|
16
16
|
# * <tt>stream_name_or_object</tt> the objects used to generate the
|
17
17
|
# channel Action Cable name, or the name itself
|
18
18
|
# * <tt>&block</tt> optional block executed before the
|
19
19
|
# assertion
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# ==== Options
|
22
22
|
#
|
23
23
|
# * <tt>count:</tt> the number of `<turbo-stream>` elements that are
|
24
24
|
# expected to be broadcast
|
@@ -64,13 +64,13 @@ module Turbo
|
|
64
64
|
else
|
65
65
|
broadcasts = "Turbo Stream broadcast".pluralize(count)
|
66
66
|
|
67
|
-
assert count == payloads.count, "Expected #{count} #{broadcasts} on #{stream_name.inspect}, but there were
|
67
|
+
assert count == payloads.count, "Expected #{count} #{broadcasts} on #{stream_name.inspect}, but there were #{payloads.count}"
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
71
|
# Asserts that no `<turbo-stream>` elements were broadcast over Action Cable
|
72
72
|
#
|
73
|
-
#
|
73
|
+
# ==== Arguments
|
74
74
|
#
|
75
75
|
# * <tt>stream_name_or_object</tt> the objects used to generate the
|
76
76
|
# channel Action Cable name, or the name itself
|
@@ -113,7 +113,7 @@ module Turbo
|
|
113
113
|
|
114
114
|
# Captures any `<turbo-stream>` elements that were broadcast over Action Cable
|
115
115
|
#
|
116
|
-
#
|
116
|
+
# ==== Arguments
|
117
117
|
#
|
118
118
|
# * <tt>stream_name_or_object</tt> the objects used to generate the
|
119
119
|
# channel Action Cable name, or the name itself
|
data/lib/turbo/engine.rb
CHANGED
@@ -5,6 +5,7 @@ module Turbo
|
|
5
5
|
isolate_namespace Turbo
|
6
6
|
config.eager_load_namespaces << Turbo
|
7
7
|
config.turbo = ActiveSupport::OrderedOptions.new
|
8
|
+
config.turbo.test_connect_after_actions = %i[visit]
|
8
9
|
config.autoload_once_paths = %W(
|
9
10
|
#{root}/app/channels
|
10
11
|
#{root}/app/controllers
|
@@ -15,8 +16,46 @@ module Turbo
|
|
15
16
|
#{root}/app/jobs
|
16
17
|
)
|
17
18
|
|
19
|
+
# If the parent application does not use Active Job, app/jobs cannot
|
20
|
+
# be eager loaded, because it references the ActiveJob constant.
|
21
|
+
#
|
22
|
+
# When turbo-rails depends on Rails 7 or above, the entire block can be
|
23
|
+
# reduced to
|
24
|
+
#
|
25
|
+
# unless defined?(ActiveJob)
|
26
|
+
# Rails.autoloaders.once.do_not_eager_load("#{root}/app/jobs")
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
initializer "turbo.no_active_job", before: :set_eager_load_paths do
|
30
|
+
unless defined?(ActiveJob)
|
31
|
+
if Rails.autoloaders.zeitwerk_enabled?
|
32
|
+
Rails.autoloaders.once.do_not_eager_load("#{root}/app/jobs")
|
33
|
+
else
|
34
|
+
# This else branch only runs in Rails 6.x + classic mode.
|
35
|
+
config.eager_load_paths.delete("#{root}/app/jobs")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# If the parent application does not use Action Cable, app/channels cannot
|
41
|
+
# be eager loaded, because it references the ActionCable constant.
|
42
|
+
#
|
43
|
+
# When turbo-rails depends on Rails 7 or above, the entire block can be
|
44
|
+
# reduced to
|
45
|
+
#
|
46
|
+
# unless defined?(ActionCable)
|
47
|
+
# Rails.autoloaders.once.do_not_eager_load("#{root}/app/channels")
|
48
|
+
# end
|
49
|
+
#
|
18
50
|
initializer "turbo.no_action_cable", before: :set_eager_load_paths do
|
19
|
-
|
51
|
+
unless defined?(ActionCable)
|
52
|
+
if Rails.autoloaders.zeitwerk_enabled?
|
53
|
+
Rails.autoloaders.once.do_not_eager_load("#{root}/app/channels")
|
54
|
+
else
|
55
|
+
# This else branch only runs in Rails 6.x + classic mode.
|
56
|
+
config.eager_load_paths.delete("#{root}/app/channels")
|
57
|
+
end
|
58
|
+
end
|
20
59
|
end
|
21
60
|
|
22
61
|
# If you don't want to precompile Turbo's assets (eg. because you're using webpack),
|
@@ -46,9 +85,17 @@ module Turbo
|
|
46
85
|
end
|
47
86
|
end
|
48
87
|
|
88
|
+
initializer "turbo.request_id_tracking" do
|
89
|
+
ActiveSupport.on_load(:action_controller) do
|
90
|
+
include Turbo::RequestIdTracking
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
49
94
|
initializer "turbo.broadcastable" do
|
50
95
|
ActiveSupport.on_load(:active_record) do
|
51
|
-
|
96
|
+
if defined?(ActiveJob)
|
97
|
+
include Turbo::Broadcastable
|
98
|
+
end
|
52
99
|
end
|
53
100
|
end
|
54
101
|
|
@@ -57,11 +104,9 @@ module Turbo
|
|
57
104
|
end
|
58
105
|
|
59
106
|
initializer "turbo.renderer" do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
turbo_streams_html
|
64
|
-
end
|
107
|
+
ActionController::Renderers.add :turbo_stream do |turbo_streams_html, options|
|
108
|
+
self.content_type = Mime[:turbo_stream] if media_type.nil?
|
109
|
+
turbo_streams_html
|
65
110
|
end
|
66
111
|
end
|
67
112
|
|
@@ -75,11 +120,18 @@ module Turbo
|
|
75
120
|
initializer "turbo.test_assertions" do
|
76
121
|
ActiveSupport.on_load(:active_support_test_case) do
|
77
122
|
require "turbo/test_assertions"
|
78
|
-
require "turbo/broadcastable/test_helper"
|
79
|
-
|
80
123
|
include Turbo::TestAssertions
|
81
124
|
end
|
82
125
|
|
126
|
+
ActiveSupport.on_load(:action_cable) do
|
127
|
+
ActiveSupport.on_load(:active_support_test_case) do
|
128
|
+
if defined?(ActiveJob)
|
129
|
+
require "turbo/broadcastable/test_helper"
|
130
|
+
include Turbo::Broadcastable::TestHelper
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
83
135
|
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
84
136
|
require "turbo/test_assertions/integration_test_assertions"
|
85
137
|
|
@@ -100,5 +152,24 @@ module Turbo
|
|
100
152
|
end
|
101
153
|
end
|
102
154
|
end
|
155
|
+
|
156
|
+
initializer "turbo.system_test_helper" do
|
157
|
+
ActiveSupport.on_load(:action_dispatch_system_test_case) do
|
158
|
+
require "turbo/system_test_helper"
|
159
|
+
include Turbo::SystemTestHelper
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
config.after_initialize do |app|
|
164
|
+
ActiveSupport.on_load(:action_dispatch_system_test_case) do
|
165
|
+
app.config.turbo.test_connect_after_actions.map do |method|
|
166
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
167
|
+
def #{method}(...) # def visit(...)
|
168
|
+
super.tap { connect_turbo_cable_stream_sources } # super.tap { connect_turbo_cable_stream_sources }
|
169
|
+
end # end
|
170
|
+
RUBY
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
103
174
|
end
|
104
175
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Turbo::SystemTestHelper
|
2
|
+
# Delay until every `<turbo-cable-stream-source>` element present in the page
|
3
|
+
# is ready to receive broadcasts
|
4
|
+
#
|
5
|
+
# test "renders broadcasted Messages" do
|
6
|
+
# message = Message.new content: "Hello, from Action Cable"
|
7
|
+
#
|
8
|
+
# visit "/"
|
9
|
+
# click_link "All Messages"
|
10
|
+
# message.save! # execute server-side code to broadcast a Message
|
11
|
+
#
|
12
|
+
# assert_text message.content
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# By default, calls to `#visit` will wait for all `<turbo-cable-stream-source>`
|
16
|
+
# elements to connect. You can control this by modifying the
|
17
|
+
# `config.turbo.test_connect_after_actions`. For example, to wait after calls to
|
18
|
+
# `#click_link`, add the following to `config/environments/test.rb`:
|
19
|
+
#
|
20
|
+
# # config/environments/test.rb
|
21
|
+
# config.turbo.test_connect_after_actions << :click_link
|
22
|
+
#
|
23
|
+
# To disable automatic connecting, set the configuration to `[]`:
|
24
|
+
#
|
25
|
+
# # config/environments/test.rb
|
26
|
+
# config.turbo.test_connect_after_actions = []
|
27
|
+
#
|
28
|
+
def connect_turbo_cable_stream_sources(**options, &block)
|
29
|
+
all(:turbo_cable_stream_source, **options, connected: false, wait: 0).each do |element|
|
30
|
+
element.assert_matches_selector(:turbo_cable_stream_source, **options, connected: true, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Asserts that a `<turbo-cable-stream-source>` element is present in the
|
35
|
+
# document
|
36
|
+
#
|
37
|
+
# ==== Arguments
|
38
|
+
#
|
39
|
+
# * <tt>locator</tt> optional locator to determine the element's
|
40
|
+
# `[signed-stream-name]` attribute. Can be of any type that is a valid
|
41
|
+
# argument to <tt>Turbo::Streams::StreamName#signed_stream_name</tt>.
|
42
|
+
#
|
43
|
+
# ==== Options
|
44
|
+
#
|
45
|
+
# * <tt>:connected</tt> matches the `[connected]` attribute
|
46
|
+
# * <tt>:channel</tt> matches the `[channel]` attribute. Can be a Class,
|
47
|
+
# String, Symbol, or Regexp
|
48
|
+
# * <tt>:signed_stream_name</tt> matches the element's `[signed-stream-name]`
|
49
|
+
# attribute. Can be of any type that is a valid
|
50
|
+
# argument to <tt>Turbo::Streams::StreamName#signed_stream_name</tt>.
|
51
|
+
#
|
52
|
+
# In addition to the filters listed above, accepts any valid Capybara global
|
53
|
+
# filter option.
|
54
|
+
def assert_turbo_cable_stream_source(...)
|
55
|
+
assert_selector(:turbo_cable_stream_source, ...)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Asserts that a `<turbo-cable-stream-source>` element is absent from the
|
59
|
+
# document
|
60
|
+
#
|
61
|
+
# ==== Arguments
|
62
|
+
#
|
63
|
+
# * <tt>locator</tt> optional locator to determine the element's
|
64
|
+
# `[signed-stream-name]` attribute. Can be of any type that is a valid
|
65
|
+
# argument to <tt>Turbo::Streams::StreamName#signed_stream_name</tt>.
|
66
|
+
#
|
67
|
+
# ==== Options
|
68
|
+
#
|
69
|
+
# * <tt>:connected</tt> matches the `[connected]` attribute
|
70
|
+
# * <tt>:channel</tt> matches the `[channel]` attribute. Can be a Class,
|
71
|
+
# String, Symbol, or Regexp
|
72
|
+
# * <tt>:signed_stream_name</tt> matches the element's `[signed-stream-name]`
|
73
|
+
# attribute. Can be of any type that is a valid
|
74
|
+
# argument to <tt>Turbo::Streams::StreamName#signed_stream_name</tt>.
|
75
|
+
#
|
76
|
+
# In addition to the filters listed above, accepts any valid Capybara global
|
77
|
+
# filter option.
|
78
|
+
def assert_no_turbo_cable_stream_source(...)
|
79
|
+
assert_no_selector(:turbo_cable_stream_source, ...)
|
80
|
+
end
|
81
|
+
|
82
|
+
Capybara.add_selector :turbo_cable_stream_source do
|
83
|
+
xpath do |locator|
|
84
|
+
xpath = XPath.descendant.where(XPath.local_name == "turbo-cable-stream-source")
|
85
|
+
xpath.where(SignedStreamNameConditions.new(locator).reduce(:|))
|
86
|
+
end
|
87
|
+
|
88
|
+
expression_filter :connected do |xpath, value|
|
89
|
+
builder(xpath).add_attribute_conditions(connected: value)
|
90
|
+
end
|
91
|
+
|
92
|
+
expression_filter :channel do |xpath, value|
|
93
|
+
builder(xpath).add_attribute_conditions(channel: value.try(:name) || value)
|
94
|
+
end
|
95
|
+
|
96
|
+
expression_filter :signed_stream_name do |xpath, value|
|
97
|
+
case value
|
98
|
+
when TrueClass, FalseClass, NilClass, Regexp
|
99
|
+
builder(xpath).add_attribute_conditions("signed-stream-name": value)
|
100
|
+
else
|
101
|
+
xpath.where(SignedStreamNameConditions.new(value).reduce(:|))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class SignedStreamNameConditions # :nodoc:
|
107
|
+
include Turbo::Streams::StreamName, Enumerable
|
108
|
+
|
109
|
+
def initialize(value)
|
110
|
+
@value = value
|
111
|
+
end
|
112
|
+
|
113
|
+
def attribute
|
114
|
+
XPath.attr(:"signed-stream-name")
|
115
|
+
end
|
116
|
+
|
117
|
+
def each
|
118
|
+
if @value.is_a?(String)
|
119
|
+
yield attribute == @value
|
120
|
+
yield attribute == signed_stream_name(@value)
|
121
|
+
elsif @value.is_a?(Array) || @value.respond_to?(:to_key)
|
122
|
+
yield attribute == signed_stream_name(@value)
|
123
|
+
elsif @value.present?
|
124
|
+
yield attribute == @value
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -4,7 +4,7 @@ module Turbo
|
|
4
4
|
# Assert that the Turbo Stream request's response body's HTML contains a
|
5
5
|
# `<turbo-stream>` element.
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# ==== Options
|
8
8
|
#
|
9
9
|
# * <tt>:status</tt> [Integer, Symbol] the HTTP response status
|
10
10
|
# * <tt>:action</tt> [String] matches the element's <tt>[action]</tt>
|
@@ -47,7 +47,7 @@ module Turbo
|
|
47
47
|
# Assert that the Turbo Stream request's response body's HTML does not
|
48
48
|
# contain a `<turbo-stream>` element.
|
49
49
|
#
|
50
|
-
#
|
50
|
+
# ==== Options
|
51
51
|
#
|
52
52
|
# * <tt>:status</tt> [Integer, Symbol] the HTTP response status
|
53
53
|
# * <tt>:action</tt> [String] matches the element's <tt>[action]</tt>
|
@@ -10,7 +10,7 @@ module Turbo
|
|
10
10
|
# Assert that the rendered fragment of HTML contains a `<turbo-stream>`
|
11
11
|
# element.
|
12
12
|
#
|
13
|
-
#
|
13
|
+
# ==== Options
|
14
14
|
#
|
15
15
|
# * <tt>:action</tt> [String] matches the element's <tt>[action]</tt>
|
16
16
|
# attribute
|
@@ -55,7 +55,7 @@ module Turbo
|
|
55
55
|
# Assert that the rendered fragment of HTML does not contain a `<turbo-stream>`
|
56
56
|
# element.
|
57
57
|
#
|
58
|
-
#
|
58
|
+
# ==== Options
|
59
59
|
#
|
60
60
|
# * <tt>:action</tt> [String] matches the element's <tt>[action]</tt>
|
61
61
|
# attribute
|
data/lib/turbo/version.rb
CHANGED
data/lib/turbo-rails.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require "turbo/engine"
|
2
|
+
require "active_support/core_ext/module/attribute_accessors_per_thread"
|
2
3
|
|
3
4
|
module Turbo
|
4
5
|
extend ActiveSupport::Autoload
|
5
6
|
|
6
7
|
mattr_accessor :draw_routes, default: true
|
7
8
|
|
9
|
+
thread_mattr_accessor :current_request_id
|
10
|
+
|
8
11
|
class << self
|
9
12
|
attr_writer :signed_stream_verifier_key
|
10
13
|
|
@@ -15,5 +18,12 @@ module Turbo
|
|
15
18
|
def signed_stream_verifier_key
|
16
19
|
@signed_stream_verifier_key or raise ArgumentError, "Turbo requires a signed_stream_verifier_key"
|
17
20
|
end
|
21
|
+
|
22
|
+
def with_request_id(request_id)
|
23
|
+
old_request_id, self.current_request_id = self.current_request_id, request_id
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
self.current_request_id = old_request_id
|
27
|
+
end
|
18
28
|
end
|
19
29
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Stephenson
|
@@ -10,22 +10,8 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2024-10-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: activejob
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
18
|
-
requirements:
|
19
|
-
- - ">="
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 6.0.0
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
requirements:
|
26
|
-
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
version: 6.0.0
|
29
15
|
- !ruby/object:Gem::Dependency
|
30
16
|
name: actionpack
|
31
17
|
requirement: !ruby/object:Gem::Requirement
|
@@ -69,6 +55,7 @@ files:
|
|
69
55
|
- app/channels/turbo/streams/broadcasts.rb
|
70
56
|
- app/channels/turbo/streams/stream_name.rb
|
71
57
|
- app/channels/turbo/streams_channel.rb
|
58
|
+
- app/controllers/concerns/turbo/request_id_tracking.rb
|
72
59
|
- app/controllers/turbo/frames/frame_request.rb
|
73
60
|
- app/controllers/turbo/native/navigation.rb
|
74
61
|
- app/controllers/turbo/native/navigation_controller.rb
|
@@ -85,11 +72,13 @@ files:
|
|
85
72
|
- app/javascript/turbo/snakeize.js
|
86
73
|
- app/jobs/turbo/streams/action_broadcast_job.rb
|
87
74
|
- app/jobs/turbo/streams/broadcast_job.rb
|
75
|
+
- app/jobs/turbo/streams/broadcast_stream_job.rb
|
88
76
|
- app/models/concerns/turbo/broadcastable.rb
|
77
|
+
- app/models/turbo/debouncer.rb
|
89
78
|
- app/models/turbo/streams/tag_builder.rb
|
79
|
+
- app/models/turbo/thread_debouncer.rb
|
90
80
|
- app/views/layouts/turbo_rails/frame.html.erb
|
91
81
|
- config/routes.rb
|
92
|
-
- lib/install/turbo_needs_redis.rb
|
93
82
|
- lib/install/turbo_with_bun.rb
|
94
83
|
- lib/install/turbo_with_importmap.rb
|
95
84
|
- lib/install/turbo_with_node.rb
|
@@ -97,13 +86,15 @@ files:
|
|
97
86
|
- lib/turbo-rails.rb
|
98
87
|
- lib/turbo/broadcastable/test_helper.rb
|
99
88
|
- lib/turbo/engine.rb
|
89
|
+
- lib/turbo/system_test_helper.rb
|
100
90
|
- lib/turbo/test_assertions.rb
|
101
91
|
- lib/turbo/test_assertions/integration_test_assertions.rb
|
102
92
|
- lib/turbo/version.rb
|
103
93
|
homepage: https://github.com/hotwired/turbo-rails
|
104
94
|
licenses:
|
105
95
|
- MIT
|
106
|
-
metadata:
|
96
|
+
metadata:
|
97
|
+
changelog_uri: https://github.com/hotwired/turbo-rails/releases
|
107
98
|
post_install_message:
|
108
99
|
rdoc_options: []
|
109
100
|
require_paths:
|
@@ -119,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
110
|
- !ruby/object:Gem::Version
|
120
111
|
version: '0'
|
121
112
|
requirements: []
|
122
|
-
rubygems_version: 3.
|
113
|
+
rubygems_version: 3.5.11
|
123
114
|
signing_key:
|
124
115
|
specification_version: 4
|
125
116
|
summary: The speed of a single-page web application without having to write any JavaScript.
|
@@ -1,20 +0,0 @@
|
|
1
|
-
if (cable_config_path = Rails.root.join("config/cable.yml")).exist?
|
2
|
-
say "Enable redis in bundle"
|
3
|
-
|
4
|
-
gemfile_content = File.read(Rails.root.join("Gemfile"))
|
5
|
-
pattern = /gem ['"]redis['"]/
|
6
|
-
|
7
|
-
if gemfile_content.match?(pattern)
|
8
|
-
uncomment_lines "Gemfile", pattern
|
9
|
-
else
|
10
|
-
append_file "Gemfile", "\n# Use Redis for Action Cable"
|
11
|
-
gem 'redis', '~> 4.0'
|
12
|
-
end
|
13
|
-
|
14
|
-
run_bundle
|
15
|
-
|
16
|
-
say "Switch development cable to use redis"
|
17
|
-
gsub_file cable_config_path.to_s, /development:\n\s+adapter: async/, "development:\n adapter: redis\n url: redis://localhost:6379/1"
|
18
|
-
else
|
19
|
-
say 'ActionCable config file (config/cable.yml) is missing. Uncomment "gem \'redis\'" in your Gemfile and create config/cable.yml to use the Turbo Streams broadcast feature.'
|
20
|
-
end
|