Serves the page of the watch mode, and makes the page reload
The server is :httpd from the inets application of OTP, so it needs no
dependency. It listens on 127.0.0.1 only, so no other computer can read the
deck. Expresso.Watch.Host also refuses a request for a different host
name, so a web page cannot read the deck with DNS rebinding.
The server serves a private directory from Expresso.PrivateDir, and that
directory holds two files:
index.html- the last good document, with a small reload script at the end of thebody.version- the number of that render.
The script asks for version two times each second. When the number is not
the number of its own document, the script reloads the page. The address
holds the slide and the step, so the page shows the same step after the
reload. The speaker view opens the same address, so it reloads too.
publish/2 writes the new document, and then the new number. Each write
goes to a temporary file, and a rename then replaces the old file. The
server thus never sends a part of a file.
The address / with a query, such as /?speaker= or /?scheme=dark, also
gets index.html. The speaker view and the variants of a theme thus work in
the watch mode.
The directory goes away when the process that started the server stops,
and when the VM stops. Expresso.PrivateDir tells how.
This module owns the server and the script, so the two always change
together. The file version and the script are internal: a later version
can push the reload over a WebSocket, and the user sees no difference. The
section "The watch mode" of docs/architecture.md gives the details.
Summary
Functions
Serve a new document, and tell each open page to reload
Start the server on a port of 127.0.0.1
Stop the server, and remove its directory
The address of the page of the server
Types
@type t() :: %Expresso.Watch.Server{ directory: Path.t(), pid: pid(), port: :inet.port_number(), private_dir: Expresso.PrivateDir.t(), version: non_neg_integer() }
A running server
Functions
Serve a new document, and tell each open page to reload
@spec start(:inet.port_number()) :: {:ok, t()} | {:error, String.t()}
Start the server on a port of 127.0.0.1
The port 0 gives a free port, and url/1 then returns the address with that
port. Until the first call of publish/2, the page shows a short text.
For a port in use, the function returns an error message that names
--port.
@spec stop(t()) :: :ok
Stop the server, and remove its directory
The address of the page of the server