Packages
phoenix_live_reload
1.4.0
1.6.2
1.6.1
1.6.0
1.5.3
1.5.2
1.5.1
1.5.0
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.4
1.2.3
retired
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.6.0
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
Provides live-reload functionality for Phoenix
Current section
Files
Jump to
Current section
Files
lib/phoenix_live_reload/channel.ex
defmodule Phoenix.LiveReloader.Channel do
@moduledoc """
Phoenix's live-reload channel.
"""
use Phoenix.Channel
require Logger
def join("phoenix:live_reload", _msg, socket) do
{:ok, _} = Application.ensure_all_started(:phoenix_live_reload)
if Process.whereis(:phoenix_live_reload_file_monitor) do
FileSystem.subscribe(:phoenix_live_reload_file_monitor)
config = socket.endpoint.config(:live_reload)
socket =
socket
|> assign(:patterns, config[:patterns] || [])
|> assign(:debounce, config[:debounce] || 0)
{:ok, socket}
else
{:error, %{message: "live reload backend not running"}}
end
end
def handle_info({:file_event, _pid, {path, _event}}, socket) do
%{patterns: patterns, debounce: debounce} = socket.assigns
if matches_any_pattern?(path, patterns) do
ext = Path.extname(path)
for {path, ext} <- [{path, ext} | debounce(debounce, [ext], patterns)] do
asset_type = remove_leading_dot(ext)
Logger.debug("Live reload: #{Path.relative_to_cwd(path)}")
push(socket, "assets_change", %{asset_type: asset_type})
end
end
{:noreply, socket}
end
defp debounce(0, _exts, _patterns), do: []
defp debounce(time, exts, patterns) when is_integer(time) and time > 0 do
Process.send_after(self(), :debounced, time)
debounce(exts, patterns)
end
defp debounce(exts, patterns) do
receive do
:debounced ->
[]
{:file_event, _pid, {path, _event}} ->
ext = Path.extname(path)
if matches_any_pattern?(path, patterns) and ext not in exts do
[{path, ext} | debounce([ext | exts], patterns)]
else
debounce(exts, patterns)
end
end
end
defp matches_any_pattern?(path, patterns) do
path = to_string(path)
Enum.any?(patterns, fn pattern ->
String.match?(path, pattern) and not String.match?(path, ~r{(^|/)_build/})
end)
end
defp remove_leading_dot("." <> rest), do: rest
defp remove_leading_dot(rest), do: rest
end