breakfast 0.1.1 → 0.2.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
  SHA1:
3
- metadata.gz: c0e5fba9fcb5dc29a25bf20a27d693cd3ac0be89
4
- data.tar.gz: 74d2d20b732e3ca1cf28fdc2376eaee375db5e10
3
+ metadata.gz: 463ac1e5499d524e1d36cd8f6d910a8ca395abc8
4
+ data.tar.gz: 1424440e64fb4f289108542cbc0d7ed0a703b8ef
5
5
  SHA512:
6
- metadata.gz: 8ef4e2360c04c4a283bf05de4b2e0c0ee4e3eead0e4f8aa2e58a3a193a2cfa10b1dac8879fb6227e586c502d68a8c3184128e3a9d8d17c866bf20ab41bd47a51
7
- data.tar.gz: 67a63d9e304c561eb5677ff9a65508c40116128f93505e8efa8c5880f0de02738bfec1ccfddeb71b9c08d6b6ab461d3cf3c26fbc605a999739a6a13fae7a494b
6
+ metadata.gz: 164488b11036281749f716663d7d5bd76d970f1c95ea135ad0694f70e907c3775858bce99c25ad955b0fe468e4d072a8323c706921f02db48c234b78ea266c04
7
+ data.tar.gz: 1449e3fb7fc8447081a0460c7d1b72e36a810c30e260bdb4436505ee9e9113e5fabd4071bc5ef0e62c1d0a00f82fd4d52d8a200788c17cdf4ca372decdd64264
@@ -1,6 +1,9 @@
1
1
  require "breakfast/version"
2
2
  require "breakfast/live_reload_channel"
3
+ require "breakfast/status_channel"
3
4
  require "breakfast/view_helper"
5
+ require "breakfast/brunch_watcher"
6
+ require "breakfast/compilation_listener"
4
7
 
5
8
  module Breakfast
6
9
  end
@@ -0,0 +1,55 @@
1
+ require "pty"
2
+
3
+ module Breakfast
4
+ class BrunchWatcher
5
+ CHANNEL = "breakfast_status".freeze
6
+ BRUNCH_COMMAND = "./node_modules/brunch/bin/brunch watch".freeze
7
+
8
+ def self.spawn(log:)
9
+ new(log: log).run
10
+ end
11
+
12
+ attr_reader :log
13
+ def initialize(log:)
14
+ @log = log
15
+ end
16
+
17
+ def run
18
+ out, writer, pid = PTY.spawn(BRUNCH_COMMAND)
19
+ writer.close
20
+
21
+ Process.detach(pid)
22
+
23
+ begin
24
+ loop do
25
+ output = out.readpartial(64.kilobytes).strip
26
+ log.debug output
27
+
28
+ output = output.gsub(/\e\[([;\d]+)?m/, '')
29
+
30
+ case output
31
+ when /compiled/
32
+ broadcast(status: "success", message: output.split("info: ").last)
33
+ when /error/
34
+ broadcast(status: "error", message: output.split("error: ").last)
35
+ end
36
+ end
37
+ rescue EOFError, Errno::EIO
38
+ log.fatal "[BREAKFAST] Watcher died unexpectedly. Restart Rails Server"
39
+ broadcast(
40
+ status: "error",
41
+ message: "Watcher died unexpectedly. Restart Rails server"
42
+ )
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def broadcast(status:, message:)
49
+ ActionCable.server.broadcast(CHANNEL, {
50
+ status: status,
51
+ message: message
52
+ })
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,22 @@
1
+ module Breakfast
2
+ class CompilationListener
3
+ EXTENSIONS = ["css", "js", "html"].freeze
4
+ CHANNEL = "breakfast_live_reload".freeze
5
+
6
+ def self.start(asset_output_folders:, view_folders:)
7
+ listen_to_paths = Array.wrap(asset_output_folders) + Array.wrap(view_folders)
8
+
9
+ listener = ::Listen.to(*listen_to_paths) do |modified, added, removed|
10
+ files = modified + added + removed
11
+
12
+ EXTENSIONS.each do |extension|
13
+ if files.any? { |file| file.match(/\.#{extension}/) }
14
+ ActionCable.server.broadcast(CHANNEL, { extension: extension })
15
+ end
16
+ end
17
+ end
18
+
19
+ listener.start
20
+ end
21
+ end
22
+ end
@@ -13,6 +13,7 @@ module BrunchRails
13
13
  config.breakfast.asset_output_folders = [Rails.root.join("public")]
14
14
  config.breakfast.view_folders = [Rails.root.join("app", "views")]
15
15
  config.breakfast.environments = %w(development)
16
+ config.breakfast.status_bar_location = :bottom
16
17
  end
17
18
 
18
19
  initializer "breakfast.setup_view_helpers" do |app|
@@ -23,24 +24,14 @@ module BrunchRails
23
24
 
24
25
  config.after_initialize do |app|
25
26
  if config.breakfast.environments.include?(Rails.env) && defined?(Rails::Server)
26
- @brunch_pid = Process.spawn("brunch watch")
27
- Process.detach(@brunch_pid)
28
-
29
- listen_to_paths = Array.wrap(config.breakfast.asset_output_folders) +
30
- Array.wrap(config.breakfast.view_folders)
31
-
32
- listener = ::Listen.to(*listen_to_paths) do |modified, added, removed|
33
- files = modified + added + removed
34
- extensions = ["css", "js", "html"].freeze
35
-
36
- extensions.each do |extension|
37
- if files.any? { |file| file.match(/\.#{extension}/) }
38
- ActionCable.server.broadcast "breakfast_live_reload", { extension: extension }
39
- end
40
- end
27
+ Thread.new do
28
+ Breakfast::BrunchWatcher.spawn(log: Rails.logger)
41
29
  end
42
30
 
43
- listener.start
31
+ Breakfast::CompilationListener.start(
32
+ asset_output_folders: config.breakfast.asset_output_folders,
33
+ view_folders: config.breakfast.view_folders
34
+ )
44
35
  end
45
36
  end
46
37
 
@@ -0,0 +1,10 @@
1
+ require "rails"
2
+
3
+ module Breakfast
4
+ class StatusChannel < ::ActionCable::Channel::Base
5
+ def subscribed
6
+ logger.info "Subscribed to channel"
7
+ stream_from "breakfast_status"
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Breakfast
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -11,7 +11,8 @@ module Breakfast
11
11
  js: "#{Rails.configuration.breakfast.js_reload_strategy}",
12
12
  css: "#{Rails.configuration.breakfast.css_reload_strategy}",
13
13
  html: "#{Rails.configuration.breakfast.html_reload_strategy}"
14
- }
14
+ },
15
+ statusBarLocation: "#{Rails.configuration.breakfast.status_bar_location}"
15
16
  });
16
17
  SCRIPT
17
18
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "breakfast-rails",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Assets for the Breakfast Gem",
5
5
  "main": "./lib/breakfast-rails.js",
6
6
  "scripts": {
@@ -1,9 +1,16 @@
1
1
  const LiveReloader = require('./live-reload');
2
+ const StatusBar = require('./status-bar');
3
+ const ActionCable = require('actioncable');
2
4
 
3
5
  const BreakfastRails = {
4
6
  init(options = {}) {
5
- const liveReloader = new LiveReloader();
6
- liveReloader.init(options);
7
+ options.cable = ActionCable.createConsumer(`ws://${options.host}:${options.port}/cable`);
8
+
9
+ const liveReloader = new LiveReloader(options);
10
+ const statusBar = new StatusBar(options);
11
+
12
+ liveReloader.init();
13
+ statusBar.init();
7
14
  }
8
15
  };
9
16
 
@@ -1,6 +1,8 @@
1
- const ActionCable = require('actioncable');
2
-
3
1
  class LiveReloader {
2
+ constructor(options = {}) {
3
+ this.options = options;
4
+ }
5
+
4
6
  buildFreshUrl(url) {
5
7
  const date = Math.round(Date.now() / 1000).toString();
6
8
  url = url.replace(/(\&|\\?)version=\d*/, '');
@@ -64,7 +66,7 @@ class LiveReloader {
64
66
  }
65
67
  }
66
68
 
67
- init(options = {}) {
69
+ init() {
68
70
  const reloaders = {
69
71
  js: this.jsReload.bind(this),
70
72
  css: this.cssReload.bind(this),
@@ -72,16 +74,12 @@ class LiveReloader {
72
74
  };
73
75
 
74
76
  document.addEventListener('DOMContentLoaded', () => {
75
- const Breakfast = window.Breakfast || {};
76
- Breakfast.options = options;
77
-
78
77
  const reloadChannel = 'Breakfast::LiveReloadChannel';
79
78
 
80
- Breakfast.cable = ActionCable.createConsumer(`ws://${options.host}:${options.port}/cable`);
81
- Breakfast.channel = Breakfast.cable.subscriptions.create(reloadChannel, {
79
+ this.options.cable.subscriptions.create(reloadChannel, {
82
80
  received: (data) => {
83
81
  const reloader = reloaders[data.extension];
84
- reloader(options.reloadStrategies[data.extension]);
82
+ reloader(this.options.reloadStrategies[data.extension]);
85
83
  }
86
84
  });
87
85
  });
@@ -0,0 +1,53 @@
1
+ const LOCAL_STORAGE_KEY = 'breakfast-last-log';
2
+ const STATUS_CHANNEL = 'Breakfast::StatusChannel';
3
+
4
+ class StatusBar {
5
+ constructor(options = {}) {
6
+ this.options = options;
7
+ }
8
+
9
+ init() {
10
+ ['DOMContentLoaded', 'turbolinks:load']
11
+ .forEach(event => document.addEventListener(event, () => {
12
+ const lastLog = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || {};
13
+ this.drawStatusBar(lastLog);
14
+
15
+ this.options.cable.subscriptions.create(STATUS_CHANNEL, {
16
+ received: (statusData) => {
17
+ localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(statusData));
18
+ this.drawStatusBar(statusData);
19
+ }
20
+ });
21
+ })
22
+ );
23
+ }
24
+
25
+ drawStatusBar(statusData = {}) {
26
+ const statusBar = document.getElementById('breakfast-status-bar');
27
+
28
+ if (statusBar) {
29
+ document.body.removeChild(statusBar);
30
+ }
31
+
32
+ const colors = {
33
+ 'success': '#539417',
34
+ 'error': '#a93131'
35
+ };
36
+
37
+ document.body.innerHTML += `
38
+ <div id="breakfast-status-bar" style="
39
+ font-family: monospace;
40
+ font-size: 13px;
41
+ position:fixed;
42
+ min-width:300px;
43
+ padding: 6px;
44
+ background: ${colors[statusData.status]};
45
+ color: #fff;
46
+ white-space: pre-wrap;
47
+ ${this.options.statusBarLocation}: 0;"
48
+ >Breakfast: ${ statusData.message }</div>
49
+ `;
50
+ }
51
+ }
52
+
53
+ module.exports = StatusBar;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: breakfast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Koperwas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-06 00:00:00.000000000 Z
11
+ date: 2016-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -113,10 +113,13 @@ files:
113
113
  - bin/setup
114
114
  - breakfast.gemspec
115
115
  - lib/breakfast.rb
116
+ - lib/breakfast/brunch_watcher.rb
116
117
  - lib/breakfast/capistrano.rb
117
118
  - lib/breakfast/capistrano/tasks/breakfast.rake
119
+ - lib/breakfast/compilation_listener.rb
118
120
  - lib/breakfast/live_reload_channel.rb
119
121
  - lib/breakfast/railtie.rb
122
+ - lib/breakfast/status_channel.rb
120
123
  - lib/breakfast/version.rb
121
124
  - lib/breakfast/view_helper.rb
122
125
  - lib/generators/breakfast/install_generator.rb
@@ -129,6 +132,7 @@ files:
129
132
  - node_package/package.json
130
133
  - node_package/src/breakfast-rails.js
131
134
  - node_package/src/live-reload.js
135
+ - node_package/src/status-bar.js
132
136
  homepage: https://github.com/devlocker/breakfast
133
137
  licenses:
134
138
  - MIT