Skip to content

Commit ccb18ab

Browse files
committed
watch mode and readme
1 parent 621066b commit ccb18ab

File tree

7 files changed

+49
-34
lines changed

7 files changed

+49
-34
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ Arguments:
2626
Options:
2727
-a, --address <ADDRESS> [default: 0.0.0.0]
2828
-p, --port <PORT> [default: 8080]
29-
--spa
29+
--spa Redirect requests to /index.html for Single Page Applications
3030
-c, --cache-time <CACHE_TIME> Cache control time [default: 0]
3131
-H, --header <HEADERS> Custom headers (Format "key:value")
3232
--cors Enable CORS header
3333
--no-cache Disable cache control header
3434
-Q, --quiet Don't print any logs to terminal
35+
-w, --watch Watch folder for changes and trigger a browser reload
3536
-h, --help Print help
3637
```
3738

dist/home.html

+11-19
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
4-
<head>
5-
<meta charset="UTF-8">
6-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7-
<title>Document</title>
8-
</head>
9-
10-
<body>
11-
<script type="module" src="./index.js"></script>
12-
<!-- <script src=".http-server-rs/reload" type="application/javascript"></script> -->
13-
<script>
14-
new EventSource(".http-server-rs/reload").onmessage = (event) => {
15-
console.log('update')
16-
};
17-
</script>
18-
</body>
19-
20-
21-
</html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Document</title>
7+
</head>
8+
9+
<body>
10+
hello worldddd
11+
<script type="module" src="./index.js"></script>
12+
</body>
13+
</html>

dist/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
console.log('hi')
1+
console.log("foobar");

src/cli.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct CliCommand {
1414
#[arg(short = 'p', long = "port", default_value = "8080")]
1515
pub port: usize,
1616

17+
/// Redirect requests to /index.html for Single Page Applications
1718
#[arg(long = "spa")]
1819
pub spa: bool,
1920

@@ -37,7 +38,7 @@ pub struct CliCommand {
3738
#[arg(short = 'Q', long = "quiet")]
3839
pub quiet: bool,
3940

40-
/// Watch folder and trigger a browser reload
41+
/// Watch folder for changes and trigger a browser reload
4142
#[arg(short = 'w', long = "watch")]
4243
pub watch: bool,
4344
}

src/explorer/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ use self::windows::get_meta_size;
2525
use crate::config::Config;
2626

2727
const DIR_PAGE: &str = include_str!("./dir.hbs");
28+
const RELOAD_SCRIPT: &str = include_str!("./reload.mjs");
29+
30+
pub fn reload_script() -> &'static str {
31+
RELOAD_SCRIPT
32+
}
2833

2934
pub fn render_directory_explorer(
3035
config: &Config,

src/explorer/reload.mjs

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
const evtSource = new EventSource(".reload");
1+
const sse = new EventSource("/.http-server-rs/reload");
22

3-
evtSource.onmessage = (event) => {
4-
const newElement = document.createElement("li");
5-
const eventList = document.getElementById("list");
6-
7-
newElement.textContent = `message: ${event.data}`;
8-
eventList.appendChild(newElement);
9-
};
3+
sse.onmessage = () => {
4+
window.location.reload();
5+
};

src/main.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::path::PathBuf;
1313
use std::sync::Arc;
1414

1515
use colored::Colorize;
16+
use explorer::reload_script;
1617
use explorer::render_directory_explorer;
1718
use fmt::Logger;
1819
use futures::TryStreamExt;
@@ -111,6 +112,15 @@ async fn main_async() -> anyhow::Result<()> {
111112
let mut file_path = config.serve_dir_abs.join(req_path.clone());
112113

113114
// If the watcher is enabled, return an event stream to the client to notify changes
115+
if req_path == ".http-server-rs/reload.js" {
116+
return Ok(
117+
res
118+
.header("Content-Type", "application/javascript")
119+
.status(200)
120+
.body(Bytes::from(reload_script()).into())?,
121+
);
122+
}
123+
114124
if req_path == ".http-server-rs/reload" {
115125
let trx_watch = trx_watch.clone();
116126

@@ -127,7 +137,7 @@ async fn main_async() -> anyhow::Result<()> {
127137
let mut rx = trx_watch.subscribe();
128138
while let Some(changes) = rx.recv().await {
129139
let msg = format!(
130-
"event:changed\ndata:{}\n\n",
140+
"data:{}\n\n",
131141
changes
132142
.into_iter()
133143
.map(|v| v.to_str().unwrap().to_string())
@@ -147,8 +157,7 @@ async fn main_async() -> anyhow::Result<()> {
147157
.header("Cache-Control", "no-cache")
148158
.header("Connection", "keep-alive")
149159
.status(hyper::StatusCode::OK)
150-
.body(boxed_body)
151-
.expect("not to fail"),
160+
.body(boxed_body)?,
152161
);
153162
}
154163

@@ -205,7 +214,7 @@ async fn main_async() -> anyhow::Result<()> {
205214

206215
// Read file
207216
// TODO not sure why tokio file read doesn't work here
208-
let Ok(contents) = fs::read(&file_path) else {
217+
let Ok(mut contents) = fs::read(&file_path) else {
209218
return Ok(
210219
res
211220
.status(500)
@@ -214,6 +223,17 @@ async fn main_async() -> anyhow::Result<()> {
214223
};
215224

216225
logger.println(format!("{} {}", "[200]".green().bold(), req.uri()));
226+
227+
if config.watch
228+
&& res
229+
.headers_ref()
230+
.unwrap()
231+
.get("Content-Type")
232+
.is_some_and(|h| h == "text/html")
233+
{
234+
contents.extend(format!("<script>{}</script>", reload_script()).as_bytes());
235+
}
236+
217237
Ok(res.status(200).body(Bytes::from(contents).into())?)
218238
}
219239
}

0 commit comments

Comments
 (0)