From 5ce9cfc0223a0c75c0e457b76bc8b95616853edb Mon Sep 17 00:00:00 2001 From: liquidev Date: Sat, 23 Nov 2024 19:12:00 +0100 Subject: [PATCH] add live reloading to the client --- crates/treehouse/src/cli/serve.rs | 12 ++++++------ crates/treehouse/src/generate.rs | 15 ++++----------- crates/treehouse/src/state.rs | 6 ++++++ .../treehouse/src/vfs/content_version_cache.rs | 1 - static/js/live-reload.js | 16 ++++++++++++++++ template/components/_head.hbs | 6 ++++++ 6 files changed, 38 insertions(+), 18 deletions(-) create mode 100644 static/js/live-reload.js diff --git a/crates/treehouse/src/cli/serve.rs b/crates/treehouse/src/cli/serve.rs index 0a24a20..cf0b7d8 100644 --- a/crates/treehouse/src/cli/serve.rs +++ b/crates/treehouse/src/cli/serve.rs @@ -103,9 +103,9 @@ async fn vfs_entry( } } -async fn system_page(target: &AsyncDir, path: &VPath) -> Response { +async fn system_page(target: &AsyncDir, path: &VPath, status_code: StatusCode) -> Response { if let Some(content) = target.content(path).await { - (StatusCode::NOT_FOUND, Html(content)).into_response() + (status_code, Html(content)).into_response() } else { ( StatusCode::INTERNAL_SERVER_ERROR, @@ -116,11 +116,11 @@ async fn system_page(target: &AsyncDir, path: &VPath) -> Response { } async fn index(State(state): State>) -> Response { - system_page(&state.target, system::INDEX).await + system_page(&state.target, system::INDEX, StatusCode::OK).await } async fn four_oh_four(State(state): State>) -> Response { - system_page(&state.target, system::FOUR_OH_FOUR).await + system_page(&state.target, system::FOUR_OH_FOUR, StatusCode::NOT_FOUND).await } async fn branch(RawQuery(named_id): RawQuery, State(state): State>) -> Response { @@ -175,8 +175,8 @@ async fn branch(RawQuery(named_id): RawQuery, State(state): State>) } } - system_page(&state.target, system::FOUR_OH_FOUR).await + system_page(&state.target, system::FOUR_OH_FOUR, StatusCode::NOT_FOUND).await } else { - system_page(&state.target, system::B_DOCS).await + system_page(&state.target, system::B_DOCS, StatusCode::OK).await } } diff --git a/crates/treehouse/src/generate.rs b/crates/treehouse/src/generate.rs index 9d63750..339505d 100644 --- a/crates/treehouse/src/generate.rs +++ b/crates/treehouse/src/generate.rs @@ -28,9 +28,7 @@ use crate::state::{FileId, Treehouse}; #[derive(Debug, Clone)] pub struct ParsedTree { root_key: String, - tree_path: String, file_id: FileId, - target_path: VPathBuf, } #[derive(Serialize)] @@ -55,6 +53,7 @@ struct BaseTemplateData<'a> { config: &'a Config, import_map: String, season: Option, + dev: bool, } #[derive(Serialize)] @@ -117,15 +116,7 @@ fn parse_tree( let root_key = tree_path.clone(); treehouse.roots.insert(root_key.clone(), roots); - Ok(( - Some(ParsedTree { - root_key, - tree_path, - file_id, - target_path, - }), - diagnostics, - )) + Ok((Some(ParsedTree { root_key, file_id }), diagnostics)) } Err(diagnostics) => Ok((None, diagnostics)), } @@ -190,6 +181,7 @@ fn generate_simple_template( import_map: serde_json::to_string_pretty(&sources.import_map) .expect("import map should be serializable to JSON"), season: Season::current(), + dev: cfg!(debug_assertions), }; handlebars .render(template_name, &base_template_data) @@ -239,6 +231,7 @@ fn generate_tree( import_map: serde_json::to_string_pretty(&sources.import_map) .expect("import map should be serializable to JSON"), season: Season::current(), + dev: cfg!(debug_assertions), }; let template_data = PageTemplateData { diff --git a/crates/treehouse/src/state.rs b/crates/treehouse/src/state.rs index f6a141a..eb2f80a 100644 --- a/crates/treehouse/src/state.rs +++ b/crates/treehouse/src/state.rs @@ -103,6 +103,12 @@ impl Treehouse { } } +impl Default for Treehouse { + fn default() -> Self { + Self::new() + } +} + pub struct TomlError { pub message: String, pub span: Option>, diff --git a/crates/treehouse/src/vfs/content_version_cache.rs b/crates/treehouse/src/vfs/content_version_cache.rs index 0149b24..3dfe74b 100644 --- a/crates/treehouse/src/vfs/content_version_cache.rs +++ b/crates/treehouse/src/vfs/content_version_cache.rs @@ -1,7 +1,6 @@ use std::fmt::{self, Debug}; use dashmap::DashMap; -use log::debug; use super::{Dir, DirEntry, EditPath, VPath, VPathBuf}; diff --git a/static/js/live-reload.js b/static/js/live-reload.js new file mode 100644 index 0000000..b43b973 --- /dev/null +++ b/static/js/live-reload.js @@ -0,0 +1,16 @@ +// NOTE: The server never fulfills this request, it stalls forever. +// Once the connection is closed, we try to connect with the server until we establish a successful +// connection. Then we reload the page. +await fetch("/dev/live-reload/stall").catch(async () => { + while (true) { + try { + let response = await fetch("/dev/live-reload/back-up"); + if (response.status == 200) { + window.location.reload(); + break; + } + } catch (e) { + await new Promise((resolve) => setTimeout(resolve, 100)); + } + } +}); diff --git a/template/components/_head.hbs b/template/components/_head.hbs index c083103..3c31fa2 100644 --- a/template/components/_head.hbs +++ b/template/components/_head.hbs @@ -17,6 +17,12 @@ clever to do while browser vendors figure that out, we'll just have to do a cach --}} +{{#if dev}} + +{{/if}} +