Packages

A convention-first web framework for Gleam

Current section

Files

Jump to
refrakt src refrakt_dev_ffi.erl
Raw

src/refrakt_dev_ffi.erl

-module(refrakt_dev_ffi).
-export([run_dev/0]).
run_dev() ->
os:putenv("APP_ENV", "dev"),
%% Check if fswatch is available for file watching
case os:find_executable("fswatch") of
false ->
%% No fswatch — just run gleam run directly
io:format("Running gleam run (no file watcher found)~n"),
io:format("Install fswatch for auto-reload: brew install fswatch~n~n"),
Port = open_port({spawn, "gleam run"}, [stream, exit_status, use_stdio, stderr_to_stdout]),
relay_and_wait(Port);
_ ->
%% fswatch available — run with auto-restart on changes
io:format("Watching src/ for changes (fswatch)~n~n"),
run_with_watch()
end.
run_with_watch() ->
%% Start gleam run
AppPort = open_port({spawn, "gleam run"}, [stream, exit_status, use_stdio, stderr_to_stdout]),
%% Start fswatch on src/ directory
WatchPort = open_port({spawn, "fswatch -1 -r src/"}, [stream, exit_status, use_stdio]),
watch_loop(AppPort, WatchPort).
watch_loop(AppPort, WatchPort) ->
receive
{AppPort, {data, Data}} ->
io:put_chars(Data),
watch_loop(AppPort, WatchPort);
{WatchPort, {data, _Data}} ->
%% File changed — kill app, rebuild, restart
io:format("~n--- File changed, rebuilding... ---~n~n"),
catch port_close(AppPort),
timer:sleep(200),
%% Rebuild
os:cmd("gleam build"),
%% Restart
NewAppPort = open_port({spawn, "gleam run"}, [stream, exit_status, use_stdio, stderr_to_stdout]),
NewWatchPort = open_port({spawn, "fswatch -1 -r src/"}, [stream, exit_status, use_stdio]),
watch_loop(NewAppPort, NewWatchPort);
{WatchPort, {exit_status, _}} ->
%% fswatch exited (got a change), restart it
NewWatchPort = open_port({spawn, "fswatch -1 -r src/"}, [stream, exit_status, use_stdio]),
watch_loop(AppPort, NewWatchPort);
{AppPort, {exit_status, Status}} ->
io:format("~nServer exited with status ~p~n", [Status]),
catch port_close(WatchPort),
nil;
_ ->
watch_loop(AppPort, WatchPort)
end.
relay_and_wait(Port) ->
receive
{Port, {data, Data}} ->
io:put_chars(Data),
relay_and_wait(Port);
{Port, {exit_status, _Status}} ->
nil;
_ ->
relay_and_wait(Port)
end.