Module: Tina4::DevReload

Defined in:
lib/tina4/dev_reload.rb

Constant Summary collapse

WATCH_EXTENSIONS =
%w[.rb .twig .html .erb .scss .css .js].freeze
WATCH_DIRS =
%w[src routes lib templates public].freeze
IGNORE_DIRS =
%w[.git node_modules vendor logs sessions .queue .keys].freeze

Class Method Summary collapse

Class Method Details

.start(root_dir: Dir.pwd, &on_change) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/tina4/dev_reload.rb', line 10

def start(root_dir: Dir.pwd, &on_change)
  require "listen"

  dirs = WATCH_DIRS
    .map { |d| File.join(root_dir, d) }
    .select { |d| Dir.exist?(d) }

  # Also watch root for .rb files
  dirs << root_dir

  Tina4::Log.info("Dev reload watching: #{dirs.join(', ')}")

  @listener = Listen.to(*dirs, only: /\.(#{WATCH_EXTENSIONS.map { |e| e.delete('.') }.join('|')})$/, ignore: build_ignore_regex) do |modified, added, removed|
    changes = { modified: modified, added: added, removed: removed }
    all_files = modified + added + removed
    next if all_files.empty?

    Tina4::Log.info("File changes detected:")
    modified.each { |f| Tina4::Log.debug("  Modified: #{f}") }
    added.each { |f| Tina4::Log.debug("  Added: #{f}") }
    removed.each { |f| Tina4::Log.debug("  Removed: #{f}") }

    # Reload Ruby files
    modified.select { |f| f.end_with?(".rb") }.each do |file|
      begin
        load file
        Tina4::Log.info("Reloaded: #{file}")
      rescue => e
        Tina4::Log.error("Reload failed: #{file} - #{e.message}")
      end
    end

    # Recompile SCSS
    scss_changes = all_files.select { |f| f.end_with?(".scss") }
    if scss_changes.any?
      Tina4::ScssCompiler.compile_all(root_dir)
    end

    on_change&.call(changes)
  end

  @listener.start
  Tina4::Log.info("Dev reload started")
end

.stopObject



55
56
57
58
# File 'lib/tina4/dev_reload.rb', line 55

def stop
  @listener&.stop
  Tina4::Log.info("Dev reload stopped")
end