roda-live_reload 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 012c722bc93152e04fca3510e45c9725b8585785
4
+ data.tar.gz: 2881387c5c17aec0f4938ba1268c5f35eebc6fbb
5
+ SHA512:
6
+ metadata.gz: 70581a36241c3c129d90e407d124ae34b1cdb8af69061de28050ed303da8af985f530e252602cf9d50127924b3e51d0f093eb613ccad84aba1130edc7149c904
7
+ data.tar.gz: ae065406eb93a0234567a574d83703bf4d41f56e6a995c3e19b91cf1f5569c1e0a42ec765b187dd9fb4cfd86d18fa68b10e5cbf041d2e0ae58a09eb73e906323
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # Roda Live Reload
2
+
3
+ A very primitive live-reload mechanism for Roda.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem "roda-live_reload"
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install roda-live_reload
20
+
21
+ ## Usage
22
+
23
+ After enabling the plugin, simply call `r.live_reload` inside your routing tree. You'll
24
+ likely want to only enable it during development.
25
+
26
+
27
+ ```ruby
28
+ class App < Roda
29
+ development = ENV.fetch("RACK_ENV", "development") == "development"
30
+
31
+ plugin :live_reload if development
32
+
33
+ route do |r|
34
+ r.live_reload if development
35
+
36
+ r.root { "Root" }
37
+ end
38
+ end
39
+ ```
40
+
41
+ ## Contributing
42
+
43
+ Bug reports and pull requests are welcome on GitHub at https://github.com/adam12/roda-live_reload.
44
+
45
+ I love pull requests! If you fork this project and modify it, please ping me to see
46
+ if your changes can be incorporated back into this project.
47
+
48
+ That said, if your feature idea is nontrivial, you should probably open an issue to
49
+ [discuss it](http://www.igvita.com/2011/12/19/dont-push-your-pull-requests/)
50
+ before attempting a pull request.
51
+
52
+ ## License
53
+
54
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+ require "listen"
3
+
4
+ module Roda::RodaPlugins # :nodoc:
5
+ # The live_reload plugin provides a chunked-body endpoint and injects a
6
+ # long-polling JavaScript function just before the closing body tag.
7
+ #
8
+ # plugin :live_reload
9
+ #
10
+ # route do |r|
11
+ # r.live_reload
12
+ # end
13
+ #
14
+ # = Plugin Options
15
+ #
16
+ # The following plugin options are supported:
17
+ #
18
+ # :watch :: Array of folders to watch. Defaults to +assets+, +views+
19
+ #
20
+ module LiveReload
21
+ module ResponseMethods # :nodoc:
22
+ INJECT = <<~EOM # :nodoc:
23
+ <script>
24
+ (function reconnect() {
25
+ var xhr = new XMLHttpRequest();
26
+
27
+ xhr.open("GET", "/_live_reload", true);
28
+
29
+ xhr.onprogress = function() {
30
+ window.location.reload();
31
+ };
32
+
33
+ xhr.onerror = function() {
34
+ console.log("Reconnecting after error");
35
+ setTimeout(reconnect, 1000);
36
+ };
37
+
38
+ xhr.onabort = function() {
39
+ console.log("Reconnecting after abort");
40
+ setTimeout(reconnect, 1000);
41
+ };
42
+
43
+ xhr.send();
44
+ })();
45
+ </script>
46
+ EOM
47
+
48
+ def finish # :nodoc:
49
+ status, headers, content = super
50
+
51
+ content = content.map do |chunk|
52
+ if chunk.include?("</body>")
53
+ chunk.sub("</body>", INJECT + "</body>")
54
+ else
55
+ chunk
56
+ end
57
+ end
58
+
59
+ headers["Content-Length"] = content.reduce(0) { |memo, chunk| memo + chunk.size }.to_s
60
+
61
+ [status, headers, content]
62
+ end
63
+ end
64
+
65
+ module RequestMethods
66
+ # Setup the live reload endpoint
67
+ def live_reload(opts = {}, &block)
68
+ on("_live_reload") do
69
+ reader, writer = IO.pipe
70
+
71
+ LiveReload.synchronize do
72
+ LiveReload.listeners.push(writer)
73
+ end
74
+
75
+ scope.stream(loop: true) do |out|
76
+ out << reader.gets
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def self.mutex # :nodoc:
83
+ @mutex ||= Mutex.new
84
+ end
85
+
86
+ def self.synchronize # :nodoc:
87
+ mutex.synchronize { yield }
88
+ end
89
+
90
+ def self.listeners # :nodoc:
91
+ @listeners ||= []
92
+ end
93
+
94
+ def self.load_dependencies(app, opts = {}) # :nodoc:
95
+ app.plugin :streaming
96
+ end
97
+
98
+ def self.configure(app, opts = {}) # :nodoc:
99
+ watch = opts.delete(:watch) || ["assets", "views"]
100
+
101
+ puts "Watching #{watch} for changes"
102
+
103
+ listener = Listen.to(*watch) do |modified, added, removed|
104
+ puts "Changes", modified, added, removed
105
+
106
+ LiveReload.listeners.each do |writer|
107
+ writer.puts "Changes"
108
+ end
109
+ end
110
+
111
+ listener.start
112
+ end
113
+ end
114
+
115
+ register_plugin :live_reload, LiveReload
116
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roda-live_reload
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Daniels
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: roda
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: listen
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubygems-tasks
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
55
+ description:
56
+ email: adam@mediadrive.ca
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - README.md
62
+ - lib/roda/plugins/live_reload.rb
63
+ homepage:
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.6.12
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Live reloading for Roda
87
+ test_files: []