Skip to content

Dev server: hot-swap stylesheets, stream changes over SSE, revalidate SCSS partials - #91

Merged
gronke merged 1 commit into
mainfrom
feat/live-reload-sse
Sep 4, 2026
Merged

gronke merged 1 commit into
mainfrom
feat/live-reload-sse

Conversation

@gronke

@gronke gronke commented Sep 4, 2026

Copy link
Copy Markdown
Owner

The dev server reloaded the whole page on any change and served a stale stylesheet after a partial edit, because the compile cache was keyed on the entry's mtime alone.

This replaces tower-livereload with a hub of our own (web_modules::live): a coalescing notify watcher maps edits to served URLs (never filesystem paths), an SSE stream (/_web_modules/live/events) publishes them, and an injected client (/_web_modules/live/live.js) hot-swaps a changed stylesheet's <link> in place and reloads the page for anything else. Compiled stylesheets record the partials they read (scss::compile_file_tracked), so the cache revalidates every dependency and a partial edit names exactly the stylesheets that include it.

The policy is the server's: --live-reload full (the default) reloads on non-CSS changes, --live-reload css only logs, --no-live-reload serves no live routes; Dev::live_reload(ReloadMode) on the builder, dev_router_with_live / serve_with_live as free functions. Hosts with their own watchers or compilers feed the same hub (record_dependencies, notify) and mount the routes where their auth wants them.

Dependencies: tower-livereload out; futures-core in (the Stream trait axum's SSE response takes, already compiled in every axum build); tokio gains sync.
The stream's no-filesystem-paths rule is recorded in SECURITY.md.

… SSE

The dev server told the browser to reload the whole page on any change and served a stale stylesheet after a partial edit, because the compile cache was keyed on the entry's mtime alone.
A change hub (`web_modules::live`) now feeds a coalescing watcher's events, mapped to the served URL, never a filesystem path, into an SSE stream; the browser client swaps a changed stylesheet's `<link>` in place and reloads the page for anything else, or only logs it under `--live-reload css`.
Compiled stylesheets record the partials they read, so the cache revalidates every dependency and a partial edit names the stylesheets that include it.
Hosts with their own compilers or watchers feed the same hub (`record_dependencies`, `notify`) and mount its routes where their auth wants them.
`tower-livereload` is replaced by `futures-core`, the trait crate axum's SSE response takes.
@gronke
gronke merged commit 85bf28f into main Sep 4, 2026
10 checks passed
@gronke
gronke deleted the feat/live-reload-sse branch September 4, 2026 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant