hotwire-livereload 1.3.1 → 1.4.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: 42f6430166f2bcdcb52940e92965a5e1d202c57b09966ddb72f76b746918b473
4
- data.tar.gz: be8743a9b6cbced10614d8fb4fc9cae8306c4355648175a91ed716a763722453
3
+ metadata.gz: 76c9e1c7f17f98e067a076d8dfc624d03aa1a7a64784da9fdde0b59f211bebe5
4
+ data.tar.gz: 3fa02e7e5a7592c61be7db173ff945f9d2f6da2e29ba4a777072702619b54473
5
5
  SHA512:
6
- metadata.gz: 909b0a55ec3d9d4dcbb0f7536e72c380a2d2d8e885cc5d988fe64f91771b759a2809d65f3fad8e500e565a51620532ae1b43c338880c7da977f396852f3b2d6b
7
- data.tar.gz: 90116c0e4b698346603d398cc3a4c7dd6616403f6caae041a014251ea24f57a5e36f83bc6e8554d1c65b21e36e92592c9a583f2f14ca042f357a7d324ecbff8d
6
+ metadata.gz: 760b3adbb7ef2bc0231f8e90f7ec3b5bfabbc2c01965518d1c69ab9885b0974cbdf0551d1f44e72a498917c55f790947fbad61ec1267973ac139ff85704c2a2f
7
+ data.tar.gz: 449e13ba3578d4fcc8e41e4939abecd29ee1a9673cdeaa7a0da24090c31de249868ae7c6541ed37c181cc4a4a23a40c6ee04f83b6922b65be3d9b0d92131d44c
data/README.md CHANGED
@@ -20,7 +20,7 @@ Run installer:
20
20
  rails livereload:install
21
21
  ```
22
22
 
23
- Folders listened by default:
23
+ Folders watched by default:
24
24
  - `app/views`
25
25
  - `app/helpers`
26
26
  - `app/javascript`
@@ -32,8 +32,16 @@ Folders listened by default:
32
32
 
33
33
  The gem detects if you use [`jsbundling-rails`](https://github.com/rails/jsbundling-rails) or [`cssbundling-rails`](https://github.com/rails/cssbundling-rails) and watches for changes in their output folder `app/assets/builds` automatically.
34
34
 
35
+ In your layout, make sure you don't `turbo-track` your JS/CSS in development:
36
+ ```diff
37
+ + <%= stylesheet_link_tag "application", "data-turbo-track": Rails.env.production? ? "reload" : "" %>
38
+ - <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
39
+ ```
40
+
35
41
  ## Configuration
36
42
 
43
+ ### Listen paths
44
+
37
45
  You can watch for changes in additional folders by adding them to `listen_paths`:
38
46
  ```ruby
39
47
  # config/environments/development.rb
@@ -44,6 +52,16 @@ Rails.application.configure do
44
52
  end
45
53
  ```
46
54
 
55
+ You can skip one or few default listen paths:
56
+ ```ruby
57
+ # config/environments/development.rb
58
+
59
+ Rails.application.configure do
60
+ # ...
61
+ config.hotwire_livereload.skip_listen_paths << Rails.root.join("app/views")
62
+ end
63
+ ```
64
+
47
65
  You can disable default listen paths and fully override them:
48
66
  ```ruby
49
67
  # config/environments/development.rb
@@ -58,6 +76,8 @@ Rails.application.configure do
58
76
  end
59
77
  ```
60
78
 
79
+ ### Force reload
80
+
61
81
  If you don't have `data-turbo-track="reload"` attribute on your JS and CSS bundles you might need to setup force reloading. This will trigger full browser reloading for JS and CSS files only:
62
82
  ```ruby
63
83
  # config/environments/development.rb
@@ -69,6 +89,8 @@ Rails.application.configure do
69
89
  end
70
90
  ```
71
91
 
92
+ ### Reload method
93
+
72
94
  Instead of a direct ActionCable websocket connection, you can reuse the existing TurboStream websocket connection and send updates using standard turbo-streams:
73
95
  ```ruby
74
96
  # config/environments/development.rb
@@ -90,6 +112,37 @@ In that case you need to place `hotwire_livereload_tags` helper in your layout *
90
112
  </head>
91
113
  ```
92
114
 
115
+ ### Listen options
116
+
117
+ [Listen gem](https://github.com/guard/listen), which is used for file system monitoring, accepts [options](https://github.com/guard/listen?tab=readme-ov-file#options) like enabling a fallback mechanism called "polling" to detect file changes.
118
+
119
+ By default, Listen uses a more efficient mechanism called "native" which relies on the operating system's file system events to detect changes. However, in some cases, such as when working with network-mounted file systems or in certain virtualized environments, the native mechanism may not work reliably. In such cases, enabling force_polling ensures that file changes are still detected, albeit with a slightly higher resource usage.
120
+
121
+ You may use listen_options to pass these options like:
122
+ ```ruby
123
+ # config/environments/development.rb
124
+
125
+ Rails.application.configure do
126
+ # ...
127
+ config.hotwire_livereload.listen_options[:force_polling] = true
128
+ end
129
+ ```
130
+
131
+ ### Listen debounce delay
132
+
133
+ If your app uses TailwindCSS or similar that compiles your CSS from looking at your templates, you can end up in a situation, where updating a template triggers twice for changes; once for the template and once for the rebuilt CSS. This can lead to unreliable reloads, ie. the reload happening before the CSS is built.
134
+
135
+ To avoid this, you can add a debounce delay to the file watcher:
136
+
137
+ ```ruby
138
+ # config/environments/development.rb
139
+
140
+ Rails.application.configure do
141
+ # ...
142
+ config.hotwire_livereload.debounce_delay_ms = 300 # in milliseconds
143
+ end
144
+ ```
145
+
93
146
  ## Disable livereload
94
147
 
95
148
  To temporarily disable livereload use:
@@ -115,6 +115,7 @@
115
115
  } else {
116
116
  console.log("[Hotwire::Livereload] Files changed. Reloading..");
117
117
  hotwire_livereload_scroll_position_default.save();
118
+ Turbo.cache.clear();
118
119
  Turbo.visit(window.location.href, { action: "replace" });
119
120
  }
120
121
  }, 300);
@@ -697,6 +697,7 @@
697
697
  } else {
698
698
  console.log("[Hotwire::Livereload] Files changed. Reloading..");
699
699
  hotwire_livereload_scroll_position_default.save();
700
+ Turbo.cache.clear();
700
701
  Turbo.visit(window.location.href, { action: "replace" });
701
702
  }
702
703
  }, 300);
@@ -10,6 +10,7 @@ export default debounce(({force_reload}) => {
10
10
  } else {
11
11
  console.log("[Hotwire::Livereload] Files changed. Reloading..")
12
12
  scrollPosition.save()
13
+ Turbo.cache.clear()
13
14
  Turbo.visit(window.location.href, { action: 'replace' })
14
15
  }
15
16
  }, 300)
@@ -8,6 +8,7 @@ module Hotwire
8
8
  isolate_namespace Hotwire::Livereload
9
9
  config.hotwire_livereload = ActiveSupport::OrderedOptions.new
10
10
  config.hotwire_livereload.listen_paths ||= []
11
+ config.hotwire_livereload.skip_listen_paths ||= []
11
12
  config.hotwire_livereload.force_reload_paths ||= []
12
13
  config.hotwire_livereload.reload_method = :action_cable
13
14
  config.hotwire_livereload.disable_default_listeners = false
@@ -15,6 +16,8 @@ module Hotwire
15
16
  #{root}/app/channels
16
17
  #{root}/app/helpers
17
18
  ]
19
+ config.hotwire_livereload.listen_options ||= {}
20
+ config.hotwire_livereload.debounce_delay_ms = 0
18
21
 
19
22
  initializer "hotwire_livereload.assets" do
20
23
  if Rails.application.config.respond_to?(:assets)
@@ -30,6 +33,7 @@ module Hotwire
30
33
 
31
34
  initializer "hotwire_livereload.set_configs" do |app|
32
35
  options = app.config.hotwire_livereload
36
+ skip_listen_paths = options.skip_listen_paths.map(&:to_s).uniq
33
37
 
34
38
  unless options.disable_default_listeners
35
39
  default_listen_paths = %w[
@@ -54,16 +58,25 @@ module Hotwire
54
58
  .uniq
55
59
  .map { |p| Rails.root.join(p) }
56
60
  .select { |p| Dir.exist?(p) }
61
+ .reject { |p| skip_listen_paths.include?(p.to_s) }
57
62
  end
58
63
  end
59
64
 
60
65
  config.after_initialize do |app|
61
66
  if Rails.env.development? && Hotwire::Livereload.server_process?
67
+ @trigger_reload = (Hotwire::Livereload.debounce(config.hotwire_livereload.debounce_delay_ms) do |options|
68
+ if config.hotwire_livereload.reload_method == :turbo_stream
69
+ Hotwire::Livereload.turbo_stream(options)
70
+ else
71
+ Hotwire::Livereload.action_cable(options)
72
+ end
73
+ end)
74
+
62
75
  options = app.config.hotwire_livereload
63
76
  listen_paths = options.listen_paths.map(&:to_s).uniq
64
77
  force_reload_paths = options.force_reload_paths.map(&:to_s).uniq.join("|")
65
78
 
66
- @listener = Listen.to(*listen_paths) do |modified, added, removed|
79
+ @listener = Listen.to(*listen_paths, **config.hotwire_livereload.listen_options) do |modified, added, removed|
67
80
  unless File.exist?(DISABLE_FILE)
68
81
  changed = [modified, removed, added].flatten.uniq
69
82
  next unless changed.any?
@@ -73,11 +86,7 @@ module Hotwire
73
86
  end
74
87
 
75
88
  options = {changed: changed, force_reload: force_reload}
76
- if config.hotwire_livereload.reload_method == :turbo_stream
77
- Hotwire::Livereload.turbo_stream(options)
78
- else
79
- Hotwire::Livereload.action_cable(options)
80
- end
89
+ @trigger_reload.call(options)
81
90
  end
82
91
  end
83
92
  @listener.start
@@ -110,5 +119,27 @@ module Hotwire
110
119
 
111
120
  puma_process || rails_server
112
121
  end
122
+
123
+ def self.debounce(wait_ms, &block)
124
+ if wait_ms.zero?
125
+ return ->(*args) { yield(*args) }
126
+ end
127
+
128
+ mutex = Mutex.new
129
+ timer_thread = nil
130
+ seconds = wait_ms.to_f / 1000.0
131
+
132
+ lambda do |*args|
133
+ mutex.synchronize do
134
+ # Cancel previous timer
135
+ timer_thread&.kill
136
+
137
+ timer_thread = Thread.new do
138
+ sleep(seconds)
139
+ yield(*args)
140
+ end
141
+ end
142
+ end
143
+ end
113
144
  end
114
145
  end
@@ -1,5 +1,5 @@
1
1
  module Hotwire
2
2
  module Livereload
3
- VERSION = "1.3.1"
3
+ VERSION = "1.4.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hotwire-livereload
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kirill Platonov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-04 00:00:00.000000000 Z
11
+ date: 2024-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties