hotwire-livereload 1.0.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +54 -16
- data/app/assets/javascripts/hotwire-livereload-turbo-stream.js +104 -0
- data/app/assets/javascripts/hotwire-livereload.js +8 -4
- data/app/helpers/hotwire/livereload/livereload_tags_helper.rb +6 -2
- data/app/javascript/hotwire-livereload-turbo-stream.js +15 -0
- data/app/javascript/hotwire-livereload.js +1 -13
- data/app/javascript/lib/hotwire-livereload-received.js +13 -0
- data/app/views/hotwire/livereload/_head_action_cable.html.erb +3 -0
- data/app/views/hotwire/livereload/_head_turbo_stream.html.erb +4 -0
- data/app/views/hotwire/livereload/_turbo_stream.html.erb +4 -0
- data/lib/hotwire/livereload/engine.rb +34 -17
- data/lib/hotwire/livereload/version.rb +1 -1
- data/lib/install/install.rb +3 -4
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a549346a2a0e4f7ca92805c4a632cb3a7e1dab47ba77f2f33fc470f202f89ef
|
4
|
+
data.tar.gz: 01de6b58b7d4a265714ca4ff668b8a579601517dc434279367d101fa058f7641
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f42175a8c4726873851f901aebce71b4df2b60550735ccca0252bb548b9c183c8be73e66b746fd64531bd86feef20e1798e38f144194a67832b92061d2ffc6c1
|
7
|
+
data.tar.gz: 81ec91c72c4af89016f35034028ef83a745a225321567d0d866ff914bb8580c45743f678907b7a3b712129eef5b9fbff807767b8b5f46f1f7f24fbcf3845925d
|
data/README.md
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
# Hotwire::Livereload
|
2
2
|
|
3
|
-
Automatically reload Hotwire Turbo when
|
3
|
+
Automatically reload Hotwire Turbo when app files are modified.
|
4
4
|
|
5
|
-
https://user-images.githubusercontent.com/839922/
|
5
|
+
https://user-images.githubusercontent.com/839922/148676469-0acfa036-832e-4b40-aa05-1fdd945baa1f.mp4
|
6
6
|
|
7
|
-
##
|
7
|
+
## Dependencies
|
8
8
|
|
9
|
-
|
9
|
+
* [Redis](https://redis.io/)
|
10
|
+
|
11
|
+
## Getting started
|
10
12
|
|
11
13
|
Add `hotwire-livereload` to your Gemfile:
|
12
14
|
```
|
13
|
-
bundle add hotwire-livereload
|
15
|
+
bundle add hotwire-livereload
|
14
16
|
```
|
15
17
|
|
16
18
|
Run installer:
|
@@ -18,9 +20,19 @@ Run installer:
|
|
18
20
|
rails livereload:install
|
19
21
|
```
|
20
22
|
|
23
|
+
Folders listened by default:
|
24
|
+
- `app/views`
|
25
|
+
- `app/helpers`
|
26
|
+
- `app/javascript`
|
27
|
+
- `app/assets/stylesheets`
|
28
|
+
- `app/assets/javascripts`
|
29
|
+
- `app/assets/images`
|
30
|
+
- `app/components`
|
31
|
+
- `config/locales`
|
32
|
+
|
21
33
|
## Configuration
|
22
34
|
|
23
|
-
You can watch for changes in additional folders by adding them to `listen_paths
|
35
|
+
You can watch for changes in additional folders by adding them to `listen_paths`:
|
24
36
|
```ruby
|
25
37
|
# config/environments/development.rb
|
26
38
|
|
@@ -30,26 +42,52 @@ Rails.application.configure do
|
|
30
42
|
end
|
31
43
|
```
|
32
44
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
45
|
+
You can disable default listen paths and fully override them:
|
46
|
+
```ruby
|
47
|
+
# config/environments/development.rb
|
48
|
+
|
49
|
+
Rails.application.configure do
|
50
|
+
# ...
|
51
|
+
config.hotwire_livereload.disable_default_listeners = true
|
52
|
+
config.hotwire_livereload.listen_paths = [
|
53
|
+
Rails.root.join("app/assets/stylesheets"),
|
54
|
+
Rails.root.join("app/javascript")
|
55
|
+
]
|
56
|
+
end
|
57
|
+
```
|
42
58
|
|
43
|
-
|
59
|
+
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:
|
44
60
|
```ruby
|
45
61
|
# config/environments/development.rb
|
46
62
|
|
47
63
|
Rails.application.configure do
|
48
64
|
# ...
|
65
|
+
config.hotwire_livereload.force_reload_paths << Rails.root.join("app/assets/stylesheets")
|
49
66
|
config.hotwire_livereload.force_reload_paths << Rails.root.join("app/javascript")
|
50
67
|
end
|
51
68
|
```
|
52
69
|
|
70
|
+
Instead of a direct ActionCable websocket connection, you can reuse the existing TurboStream websocket connection and send updates using standard turbo-streams:
|
71
|
+
```ruby
|
72
|
+
# config/environments/development.rb
|
73
|
+
|
74
|
+
Rails.application.configure do
|
75
|
+
# ...
|
76
|
+
config.hotwire_livereload.reload_method = :turbo_stream
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
In that case you need to place `hotwire_livereload_tags` helper in your layout *after* the `<%= action_cable_meta_tag %>`.
|
81
|
+
|
82
|
+
```diff
|
83
|
+
<head>
|
84
|
+
...
|
85
|
+
<%= action_cable_meta_tag %>
|
86
|
+
+ <%= hotwire_livereload_tags if Rails.env.development? %>
|
87
|
+
...
|
88
|
+
</head>
|
89
|
+
```
|
90
|
+
|
53
91
|
## Disable livereload
|
54
92
|
|
55
93
|
To temporarily disable livereload use:
|
@@ -0,0 +1,104 @@
|
|
1
|
+
(() => {
|
2
|
+
var __create = Object.create;
|
3
|
+
var __defProp = Object.defineProperty;
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
8
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
9
|
+
var __commonJS = (cb, mod) => function __require() {
|
10
|
+
return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
11
|
+
};
|
12
|
+
var __reExport = (target, module, desc) => {
|
13
|
+
if (module && typeof module === "object" || typeof module === "function") {
|
14
|
+
for (let key of __getOwnPropNames(module))
|
15
|
+
if (!__hasOwnProp.call(target, key) && key !== "default")
|
16
|
+
__defProp(target, key, { get: () => module[key], enumerable: !(desc = __getOwnPropDesc(module, key)) || desc.enumerable });
|
17
|
+
}
|
18
|
+
return target;
|
19
|
+
};
|
20
|
+
var __toModule = (module) => {
|
21
|
+
return __reExport(__markAsModule(__defProp(module != null ? __create(__getProtoOf(module)) : {}, "default", module && module.__esModule && "default" in module ? { get: () => module.default, enumerable: true } : { value: module, enumerable: true })), module);
|
22
|
+
};
|
23
|
+
|
24
|
+
// node_modules/debounce/index.js
|
25
|
+
var require_debounce = __commonJS({
|
26
|
+
"node_modules/debounce/index.js"(exports, module) {
|
27
|
+
function debounce2(func, wait, immediate) {
|
28
|
+
var timeout, args, context, timestamp, result;
|
29
|
+
if (wait == null)
|
30
|
+
wait = 100;
|
31
|
+
function later() {
|
32
|
+
var last = Date.now() - timestamp;
|
33
|
+
if (last < wait && last >= 0) {
|
34
|
+
timeout = setTimeout(later, wait - last);
|
35
|
+
} else {
|
36
|
+
timeout = null;
|
37
|
+
if (!immediate) {
|
38
|
+
result = func.apply(context, args);
|
39
|
+
context = args = null;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
;
|
44
|
+
var debounced = function() {
|
45
|
+
context = this;
|
46
|
+
args = arguments;
|
47
|
+
timestamp = Date.now();
|
48
|
+
var callNow = immediate && !timeout;
|
49
|
+
if (!timeout)
|
50
|
+
timeout = setTimeout(later, wait);
|
51
|
+
if (callNow) {
|
52
|
+
result = func.apply(context, args);
|
53
|
+
context = args = null;
|
54
|
+
}
|
55
|
+
return result;
|
56
|
+
};
|
57
|
+
debounced.clear = function() {
|
58
|
+
if (timeout) {
|
59
|
+
clearTimeout(timeout);
|
60
|
+
timeout = null;
|
61
|
+
}
|
62
|
+
};
|
63
|
+
debounced.flush = function() {
|
64
|
+
if (timeout) {
|
65
|
+
result = func.apply(context, args);
|
66
|
+
context = args = null;
|
67
|
+
clearTimeout(timeout);
|
68
|
+
timeout = null;
|
69
|
+
}
|
70
|
+
};
|
71
|
+
return debounced;
|
72
|
+
}
|
73
|
+
debounce2.debounce = debounce2;
|
74
|
+
module.exports = debounce2;
|
75
|
+
}
|
76
|
+
});
|
77
|
+
|
78
|
+
// app/javascript/lib/hotwire-livereload-received.js
|
79
|
+
var import_debounce = __toModule(require_debounce());
|
80
|
+
var hotwire_livereload_received_default = (0, import_debounce.default)(({ force_reload }) => {
|
81
|
+
const onErrorPage = document.title === "Action Controller: Exception caught";
|
82
|
+
if (onErrorPage || force_reload) {
|
83
|
+
console.log("[Hotwire::Livereload] Files changed. Force reloading..");
|
84
|
+
document.location.reload();
|
85
|
+
} else {
|
86
|
+
console.log("[Hotwire::Livereload] Files changed. Reloading..");
|
87
|
+
Turbo.visit(window.location.href, { action: "replace" });
|
88
|
+
}
|
89
|
+
}, 300);
|
90
|
+
|
91
|
+
// app/javascript/hotwire-livereload-turbo-stream.js
|
92
|
+
(() => {
|
93
|
+
if (window.HotwireLivereload) {
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
window.HotwireLivereload = function({ target }) {
|
97
|
+
const element = target.querySelector("template")?.content.getElementById("hotwire-livereload");
|
98
|
+
if (element) {
|
99
|
+
hotwire_livereload_received_default({ force_reload: element.dataset.forceReload });
|
100
|
+
}
|
101
|
+
};
|
102
|
+
document.addEventListener("turbo:before-stream-render", window.HotwireLivereload);
|
103
|
+
})();
|
104
|
+
})();
|
@@ -599,20 +599,24 @@
|
|
599
599
|
|
600
600
|
// app/javascript/hotwire-livereload.js
|
601
601
|
var import_actioncable = __toModule(require_action_cable());
|
602
|
+
|
603
|
+
// app/javascript/lib/hotwire-livereload-received.js
|
602
604
|
var import_debounce = __toModule(require_debounce());
|
603
|
-
var
|
604
|
-
var received = (0, import_debounce.default)(({ force_reload }) => {
|
605
|
+
var hotwire_livereload_received_default = (0, import_debounce.default)(({ force_reload }) => {
|
605
606
|
const onErrorPage = document.title === "Action Controller: Exception caught";
|
606
607
|
if (onErrorPage || force_reload) {
|
607
608
|
console.log("[Hotwire::Livereload] Files changed. Force reloading..");
|
608
609
|
document.location.reload();
|
609
610
|
} else {
|
610
611
|
console.log("[Hotwire::Livereload] Files changed. Reloading..");
|
611
|
-
Turbo.visit(window.location.href);
|
612
|
+
Turbo.visit(window.location.href, { action: "replace" });
|
612
613
|
}
|
613
614
|
}, 300);
|
615
|
+
|
616
|
+
// app/javascript/hotwire-livereload.js
|
617
|
+
var consumer = (0, import_actioncable.createConsumer)();
|
614
618
|
consumer.subscriptions.create("Hotwire::Livereload::ReloadChannel", {
|
615
|
-
received,
|
619
|
+
received: hotwire_livereload_received_default,
|
616
620
|
connected() {
|
617
621
|
console.log("[Hotwire::Livereload] Websocket connected");
|
618
622
|
},
|
@@ -1,7 +1,11 @@
|
|
1
1
|
module Hotwire::Livereload::LivereloadTagsHelper
|
2
2
|
def hotwire_livereload_tags
|
3
|
-
|
3
|
+
partial = if Hotwire::Livereload::Engine.config.hotwire_livereload.reload_method == :turbo_stream
|
4
|
+
'hotwire/livereload/head_turbo_stream'
|
5
|
+
else
|
6
|
+
'hotwire/livereload/head_action_cable'
|
7
|
+
end
|
4
8
|
|
5
|
-
|
9
|
+
render partial
|
6
10
|
end
|
7
11
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import received from "./lib/hotwire-livereload-received"
|
2
|
+
|
3
|
+
(() => {
|
4
|
+
if(window.HotwireLivereload){ return; }
|
5
|
+
|
6
|
+
window.HotwireLivereload = function({ target }) {
|
7
|
+
const element = target.querySelector('template')?.content.getElementById('hotwire-livereload')
|
8
|
+
if (element) {
|
9
|
+
received({ force_reload: element.dataset.forceReload })
|
10
|
+
}
|
11
|
+
};
|
12
|
+
|
13
|
+
document.addEventListener('turbo:before-stream-render', window.HotwireLivereload);
|
14
|
+
})();
|
15
|
+
|
@@ -1,19 +1,7 @@
|
|
1
1
|
import { createConsumer } from "@rails/actioncable"
|
2
|
-
import
|
2
|
+
import received from "./lib/hotwire-livereload-received"
|
3
3
|
|
4
4
|
const consumer = createConsumer()
|
5
|
-
const received = debounce(({force_reload}) => {
|
6
|
-
const onErrorPage = document.title === "Action Controller: Exception caught"
|
7
|
-
|
8
|
-
if (onErrorPage || force_reload) {
|
9
|
-
console.log("[Hotwire::Livereload] Files changed. Force reloading..")
|
10
|
-
document.location.reload()
|
11
|
-
} else {
|
12
|
-
console.log("[Hotwire::Livereload] Files changed. Reloading..")
|
13
|
-
Turbo.visit(window.location.href)
|
14
|
-
}
|
15
|
-
}, 300)
|
16
|
-
|
17
5
|
consumer.subscriptions.create("Hotwire::Livereload::ReloadChannel", {
|
18
6
|
received,
|
19
7
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import debounce from "debounce"
|
2
|
+
|
3
|
+
export default debounce(({force_reload}) => {
|
4
|
+
const onErrorPage = document.title === "Action Controller: Exception caught"
|
5
|
+
|
6
|
+
if (onErrorPage || force_reload) {
|
7
|
+
console.log("[Hotwire::Livereload] Files changed. Force reloading..")
|
8
|
+
document.location.reload()
|
9
|
+
} else {
|
10
|
+
console.log("[Hotwire::Livereload] Files changed. Reloading..")
|
11
|
+
Turbo.visit(window.location.href, { action: 'replace' })
|
12
|
+
}
|
13
|
+
}, 300)
|
@@ -9,6 +9,8 @@ module Hotwire
|
|
9
9
|
config.hotwire_livereload = ActiveSupport::OrderedOptions.new
|
10
10
|
config.hotwire_livereload.listen_paths ||= []
|
11
11
|
config.hotwire_livereload.force_reload_paths ||= []
|
12
|
+
config.hotwire_livereload.reload_method = :action_cable
|
13
|
+
config.hotwire_livereload.disable_default_listeners = false
|
12
14
|
config.autoload_once_paths = %W(
|
13
15
|
#{root}/app/channels
|
14
16
|
#{root}/app/helpers
|
@@ -16,7 +18,7 @@ module Hotwire
|
|
16
18
|
|
17
19
|
initializer "hotwire_livereload.assets" do
|
18
20
|
if Rails.application.config.respond_to?(:assets)
|
19
|
-
Rails.application.config.assets.precompile += %w( hotwire-livereload.js )
|
21
|
+
Rails.application.config.assets.precompile += %w( hotwire-livereload.js hotwire-livereload-turbo-stream.js)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -27,19 +29,21 @@ module Hotwire
|
|
27
29
|
end
|
28
30
|
|
29
31
|
initializer "hotwire_livereload.set_configs" do |app|
|
30
|
-
default_listen_paths = %w[
|
31
|
-
app/views
|
32
|
-
app/helpers
|
33
|
-
app/javascript
|
34
|
-
app/assets/stylesheets
|
35
|
-
app/assets/javascripts
|
36
|
-
app/assets/images
|
37
|
-
app/components
|
38
|
-
config/locales
|
39
|
-
].map { |p| Rails.root.join(p) }
|
40
|
-
|
41
32
|
options = app.config.hotwire_livereload
|
42
|
-
|
33
|
+
|
34
|
+
unless options.disable_default_listeners
|
35
|
+
default_listen_paths = %w[
|
36
|
+
app/views
|
37
|
+
app/helpers
|
38
|
+
app/javascript
|
39
|
+
app/assets/stylesheets
|
40
|
+
app/assets/javascripts
|
41
|
+
app/assets/images
|
42
|
+
app/components
|
43
|
+
config/locales
|
44
|
+
].map { |p| Rails.root.join(p) }
|
45
|
+
options.listen_paths += default_listen_paths.select { |p| Dir.exist?(p) }
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
49
|
config.after_initialize do |app|
|
@@ -57,10 +61,12 @@ module Hotwire
|
|
57
61
|
path.match(%r{#{force_reload_paths}})
|
58
62
|
end
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
+
options = {changed: changed, force_reload: force_reload}
|
65
|
+
if config.hotwire_livereload.reload_method == :turbo_stream
|
66
|
+
Hotwire::Livereload.turbo_stream(options)
|
67
|
+
else
|
68
|
+
Hotwire::Livereload.action_cable(options)
|
69
|
+
end
|
64
70
|
end
|
65
71
|
end
|
66
72
|
@listener.start
|
@@ -73,5 +79,16 @@ module Hotwire
|
|
73
79
|
end
|
74
80
|
end
|
75
81
|
end
|
82
|
+
|
83
|
+
def self.turbo_stream(locals)
|
84
|
+
Turbo::StreamsChannel.broadcast_replace_to('hotwire-livereload',
|
85
|
+
target: 'hotwire-livereload',
|
86
|
+
partial: 'hotwire/livereload/turbo_stream',
|
87
|
+
locals: locals)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.action_cable(opts)
|
91
|
+
ActionCable.server.broadcast("hotwire-reload", opts)
|
92
|
+
end
|
76
93
|
end
|
77
94
|
end
|
data/lib/install/install.rb
CHANGED
@@ -4,21 +4,20 @@ CABLE_CONFIG_PATH = Rails.root.join("config/cable.yml")
|
|
4
4
|
if APP_LAYOUT_PATH.exist?
|
5
5
|
say "Add Hotwire Livereload tag in application layout"
|
6
6
|
content = <<-HTML
|
7
|
-
\n
|
8
|
-
<%= javascript_include_tag "hotwire-livereload", defer: true %>
|
9
|
-
<% end %>
|
7
|
+
\n <%= hotwire_livereload_tags if Rails.env.development? %>
|
10
8
|
HTML
|
11
9
|
insert_into_file APP_LAYOUT_PATH, content.chop, before: /\s*<\/head>/
|
12
10
|
else
|
13
11
|
say "Default application.html.erb is missing!", :red
|
14
12
|
say %( Add <%= hotwire_livereload_tags %> within the <head> tag in your custom layout.)
|
13
|
+
say %( If using `config.hotwire_livereload.reload_method = :turbo_stream`, place *after* the `<%= action_cable_meta_tag %>`.)
|
15
14
|
end
|
16
15
|
|
17
16
|
if CABLE_CONFIG_PATH.exist?
|
18
17
|
gemfile = File.read(Rails.root.join("Gemfile"))
|
19
18
|
if gemfile.include?("redis")
|
20
19
|
say "Uncomment redis in Gemfile"
|
21
|
-
uncomment_lines "Gemfile", %
|
20
|
+
uncomment_lines "Gemfile", %r{gem ['"]redis['"]}
|
22
21
|
else
|
23
22
|
say "Add redis to Gemfile"
|
24
23
|
gem "redis"
|
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.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kirill Platonov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -47,10 +47,16 @@ extra_rdoc_files: []
|
|
47
47
|
files:
|
48
48
|
- MIT-LICENSE
|
49
49
|
- README.md
|
50
|
+
- app/assets/javascripts/hotwire-livereload-turbo-stream.js
|
50
51
|
- app/assets/javascripts/hotwire-livereload.js
|
51
52
|
- app/channels/hotwire/livereload/reload_channel.rb
|
52
53
|
- app/helpers/hotwire/livereload/livereload_tags_helper.rb
|
54
|
+
- app/javascript/hotwire-livereload-turbo-stream.js
|
53
55
|
- app/javascript/hotwire-livereload.js
|
56
|
+
- app/javascript/lib/hotwire-livereload-received.js
|
57
|
+
- app/views/hotwire/livereload/_head_action_cable.html.erb
|
58
|
+
- app/views/hotwire/livereload/_head_turbo_stream.html.erb
|
59
|
+
- app/views/hotwire/livereload/_turbo_stream.html.erb
|
54
60
|
- lib/hotwire/livereload.rb
|
55
61
|
- lib/hotwire/livereload/engine.rb
|
56
62
|
- lib/hotwire/livereload/version.rb
|
@@ -75,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
81
|
- !ruby/object:Gem::Version
|
76
82
|
version: '0'
|
77
83
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
84
|
+
rubygems_version: 3.3.7
|
79
85
|
signing_key:
|
80
86
|
specification_version: 4
|
81
87
|
summary: Automatically reload Hotwire Turbo when app files are modified.
|