Documentation
¶
Overview ¶
Package dev provides dev-mode-only helpers (livereload, debug surfaces). Everything in this package no-ops in production by design.
Index ¶
Constants ¶
const ( LiveReloadStreamURL = "/__livereload" LiveReloadScriptURL = "/__livereload.js" )
LiveReloadStreamURL is the SSE endpoint the dev client connects to. LiveReloadScriptURL is the tiny EventSource client script.
Variables ¶
This section is empty.
Functions ¶
func DevMCPEnabled ¶ added in v0.25.0
func DevMCPEnabled() bool
DevMCPEnabled reports whether the dev-only MCP agent surface should auto-activate: the /mcp mount, the read-only introspection tools, the mutating control tools, and battery debug tools (battery/log) all key off this. Mirrors LiveReloadEnabled's gate:
- GOFASTR_ENV naming a production-like environment → off.
- GOFASTR_DEV must be ParseBool-truthy (set by `gofastr dev`).
- GOFASTR_DEV_MCP set to a falsy ParseBool value → opt-out even when GOFASTR_DEV is set.
- Otherwise on.
Rationale: `gofastr dev` means "a local, trusted loop where the primary consumer is the developer's own agent" — the same reasoning that auto-wires livereload. Production processes never see GOFASTR_DEV, so none of this activates there.
func LiveReloadEnabled ¶
func LiveReloadEnabled() bool
LiveReloadEnabled reports whether dev-mode livereload should auto-wire.
Rules:
- GOFASTR_ENV looking like a non-dev environment → always off (case-insensitive: production, prod, live, staging).
- GOFASTR_DEV must be set to a strconv.ParseBool truthy value (1, t, T, TRUE, true, True) — typically by `gofastr dev`. Unparseable / falsy values keep livereload off so a stray GOFASTR_DEV="false" or ="no" never trips it on.
- GOFASTR_DEV_LIVERELOAD set to a falsy ParseBool value → opt-out even when GOFASTR_DEV is set.
- Otherwise on.
func LiveReloadHTMLInjector ¶ added in v0.24.0
func LiveReloadHTMLInjector() router.Middleware
LiveReloadHTMLInjector returns dev-only middleware that splices the livereload client into full HTML documents that don't already carry it. uihost pages inject the script themselves; this covers every OTHER way an app serves a page under `gofastr dev` — static.Handler file serving (the SPA and static-site shapes), widget-server pages, hand-rolled handlers that set a text/html Content-Type — so "edit → rebuild → browser refreshes" holds across the whole surface, not just uihost screens.
What is deliberately left alone:
- responses without an explicit text/html Content-Type (no sniffing);
- fragments: anything without a closing </body> (island RPC swaps, SPA-nav partials) — an appended script node would corrupt the DOM the runtime swaps them into;
- encoded bodies (Content-Encoding) — opaque bytes even when labeled HTML;
- HEAD and Range requests — http.ServeFile/ServeContent semantics (real Content-Length with no body, 206 byte ranges) must survive;
- streams: SSE and anything the handler Flushes pass through unbuffered, and a Flush mid-HTML abandons injection so progressive rendering keeps painting;
- hijacked connections (WebSocket upgrades) — Hijack is forwarded and the wrapper never writes afterwards.
func MaybeRegisterLiveReload ¶
MaybeRegisterLiveReload calls RegisterLiveReload only if LiveReloadEnabled() returns true. Used by framework.NewApp to auto-wire without forcing the route on every test that constructs a router.
func RegisterLiveReload ¶
RegisterLiveReload installs the SSE endpoint and client script on r. Idempotent — safe to call multiple times on the same router. If the router already has either pattern registered (e.g. the host wired a hand-rolled livereload before upgrading), the call is a no-op so the upgrade path doesn't panic on http.ServeMux duplicate-pattern.
func SetHeartbeatIntervalForTest ¶
SetHeartbeatIntervalForTest swaps the SSE heartbeat interval and returns a restore function. For tests only — production callers must use the default. Pass *testing.T to make the intent unambiguous.
Types ¶
This section is empty.