hotwire-livereload 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -2
- data/app/assets/javascripts/hotwire-livereload-turbo-stream.js +104 -0
- data/app/assets/javascripts/hotwire-livereload.js +8 -4
- data/app/channels/hotwire/livereload/reload_channel.rb +2 -0
- 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 +19 -5
- 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: cdb5e0a8c1342dc5af1e3a27db5ddf0bda5cc2a9ce76c14c5394ab8663738fe2
|
4
|
+
data.tar.gz: 7fb9d5acc0fdaf8e27fa2b7f59efb0d721e5fe3b49c979f7e8f4984963d8f0cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a52ac26354b673196a82b73092c9db51ad6dd77a0da1024d74c4193afb6e21abd981e7fc6b66f1b37d314ff2ce98b2e653e209a1047b5e3c0488ebd316b99ea
|
7
|
+
data.tar.gz: 002a116713b349590ed9f6c288b1290ab7760e7d128e878d8373abac46dba9bfc638fdadb3dc0d7b3d8e60cec2021315dc2a1e6a29012242c6f26cd7e9404722
|
data/README.md
CHANGED
@@ -4,11 +4,15 @@ Automatically reload Hotwire Turbo when app files are modified.
|
|
4
4
|
|
5
5
|
https://user-images.githubusercontent.com/839922/148676469-0acfa036-832e-4b40-aa05-1fdd945baa1f.mp4
|
6
6
|
|
7
|
-
##
|
7
|
+
## Dependencies
|
8
|
+
|
9
|
+
* [Redis](https://redis.io/)
|
10
|
+
|
11
|
+
## Getting started
|
8
12
|
|
9
13
|
Add `hotwire-livereload` to your Gemfile:
|
10
14
|
```
|
11
|
-
bundle add hotwire-livereload
|
15
|
+
bundle add hotwire-livereload
|
12
16
|
```
|
13
17
|
|
14
18
|
Run installer:
|
@@ -63,6 +67,27 @@ Rails.application.configure do
|
|
63
67
|
end
|
64
68
|
```
|
65
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
|
+
|
66
91
|
## Disable livereload
|
67
92
|
|
68
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,7 @@ 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
|
12
13
|
config.hotwire_livereload.disable_default_listeners = false
|
13
14
|
config.autoload_once_paths = %W(
|
14
15
|
#{root}/app/channels
|
@@ -17,7 +18,7 @@ module Hotwire
|
|
17
18
|
|
18
19
|
initializer "hotwire_livereload.assets" do
|
19
20
|
if Rails.application.config.respond_to?(:assets)
|
20
|
-
Rails.application.config.assets.precompile += %w( hotwire-livereload.js )
|
21
|
+
Rails.application.config.assets.precompile += %w( hotwire-livereload.js hotwire-livereload-turbo-stream.js)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
@@ -60,10 +61,12 @@ module Hotwire
|
|
60
61
|
path.match(%r{#{force_reload_paths}})
|
61
62
|
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
67
70
|
end
|
68
71
|
end
|
69
72
|
@listener.start
|
@@ -76,5 +79,16 @@ module Hotwire
|
|
76
79
|
end
|
77
80
|
end
|
78
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
|
79
93
|
end
|
80
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.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: 2022-
|
11
|
+
date: 2022-06-20 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.15
|
79
85
|
signing_key:
|
80
86
|
specification_version: 4
|
81
87
|
summary: Automatically reload Hotwire Turbo when app files are modified.
|