Skip to content

Commit be0e530

Browse files
authored
feat!: improve live reload (#4)
Simplifies the code as well as massively improves the debouncing behavior. CHANGE: The debounce value now defaults to 100ms instead of 0ms. BREAKING-CHANGE: The live reload function now sends just the message `:reload` to the calling process instead of `{:reload, extension}`.
1 parent 4b7e4fb commit be0e530

File tree

2 files changed

+13
-41
lines changed

2 files changed

+13
-41
lines changed

lib/web_dev_utils/code_reloader.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,3 @@ defmodule WebDevUtils.CodeReloader do
5050
Mix.Task.run("compile.elixir")
5151
end
5252
end
53-

lib/web_dev_utils/live_reload.ex

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,27 @@ defmodule WebDevUtils.LiveReload do
1212

1313
def reload!({:file_event, _watcher_pid, {path, _event}}, opts \\ []) do
1414
patterns = Keyword.get(opts, :patterns, [])
15-
debounce = Keyword.get(opts, :debounce, 0)
16-
callback = Keyword.get(opts, :callback, &Function.identity/1)
15+
debounce = Keyword.get(opts, :debounce, 100)
1716

18-
if matches_any_pattern?(path, patterns) do
19-
ext = Path.extname(path)
17+
Process.sleep(debounce)
2018

21-
for {path, ext} <- [{path, ext} | debounce(debounce, [ext], patterns)] do
22-
asset_type = remove_leading_dot(ext)
23-
Logger.debug("Live reload: #{Path.relative_to_cwd(path)}")
19+
paths = flush([Path.relative_to_cwd(to_string(path))])
2420

25-
callback.(path)
21+
path = Enum.find(paths, fn path -> Enum.any?(patterns, &String.match?(path, &1)) end)
2622

27-
send(self(), {:reload, asset_type})
28-
end
29-
end
30-
end
31-
32-
defp debounce(0, _exts, _patterns), do: []
23+
if path do
24+
Logger.debug("Live reload: #{Path.relative_to_cwd(path)}")
3325

34-
defp debounce(time, exts, patterns) when is_integer(time) and time > 0 do
35-
Process.send_after(self(), :debounced, time)
36-
debounce(exts, patterns)
26+
send(self(), :reload)
27+
end
3728
end
3829

39-
defp debounce(exts, patterns) do
30+
defp flush(acc) do
4031
receive do
41-
:debounced ->
42-
[]
43-
44-
{:file_event, _pid, {path, _event}} ->
45-
ext = Path.extname(path)
46-
47-
if matches_any_pattern?(path, patterns) and ext not in exts do
48-
[{path, ext} | debounce([ext | exts], patterns)]
49-
else
50-
debounce(exts, patterns)
51-
end
32+
{:file_event, _, {path, _event}} ->
33+
flush([Path.relative_to_cwd(to_string(path)) | acc])
34+
after
35+
0 -> acc
5236
end
5337
end
54-
55-
defp matches_any_pattern?(path, patterns) do
56-
path = to_string(path)
57-
58-
Enum.any?(patterns, fn pattern ->
59-
String.match?(path, pattern) and not String.match?(path, ~r{(^|/)_build/})
60-
end)
61-
end
62-
63-
defp remove_leading_dot("." <> rest), do: rest
64-
defp remove_leading_dot(rest), do: rest
6538
end

0 commit comments

Comments
 (0)