diff --git a/packages/hot-reload/src/lib.rs b/packages/hot-reload/src/lib.rs index 4918b0c03..40438fe62 100644 --- a/packages/hot-reload/src/lib.rs +++ b/packages/hot-reload/src/lib.rs @@ -5,6 +5,7 @@ use std::{ sync::{Arc, Mutex}, }; +use dioxus_core::Template; pub use dioxus_hot_reload_macro::hot_reload; use dioxus_html::HtmlCtx; use dioxus_rsx::hot_reload::{FileMap, UpdateResult}; @@ -15,13 +16,30 @@ pub fn init(path: &'static str) { if let Ok(crate_dir) = PathBuf::from_str(path) { let temp_file = std::env::temp_dir().join("@dioxusin"); let channels = Arc::new(Mutex::new(Vec::new())); + let file_map = Arc::new(Mutex::new(FileMap::::new(crate_dir.clone()))); if let Ok(local_socket_stream) = LocalSocketListener::bind(temp_file.as_path()) { // listen for connections std::thread::spawn({ + let file_map = file_map.clone(); let channels = channels.clone(); move || { for connection in local_socket_stream.incoming() { - if let Ok(connection) = connection { + if let Ok(mut connection) = connection { + // send any templates than have changed before the socket connected + let templates: Vec<_> = { + file_map + .lock() + .unwrap() + .map + .values() + .filter_map(|(_, template_slot)| *template_slot) + .collect() + }; + for template in templates { + if !send_template(template, &mut connection) { + continue; + } + } channels.lock().unwrap().push(connection); println!("Connected to hot reloading 🚀"); } @@ -32,7 +50,6 @@ pub fn init(path: &'static str) { // watch for changes std::thread::spawn(move || { let mut last_update_time = chrono::Local::now().timestamp(); - let mut file_map = FileMap::::new(crate_dir.clone()); let (tx, rx) = std::sync::mpsc::channel(); @@ -58,13 +75,21 @@ pub fn init(path: &'static str) { } // find changes to the rsx in the file - match file_map.update_rsx(&path, crate_dir.as_path()) { + match file_map + .lock() + .unwrap() + .update_rsx(&path, crate_dir.as_path()) + { UpdateResult::UpdatedRsx(msgs) => { for msg in msgs { - for channel in channels.iter_mut() { - let msg = serde_json::to_string(&msg).unwrap(); - channel.write_all(msg.as_bytes()).unwrap(); - channel.write_all(&[b'\n']).unwrap(); + let mut i = 0; + while i < channels.len() { + let channel = &mut channels[i]; + if send_template(msg, channel) { + i += 1; + } else { + channels.remove(i); + } } } } @@ -82,3 +107,17 @@ pub fn init(path: &'static str) { } } } + +fn send_template(template: Template<'static>, channel: &mut impl Write) -> bool { + if let Ok(msg) = serde_json::to_string(&template) { + if channel.write_all(msg.as_bytes()).is_err() { + return false; + } + if channel.write_all(&[b'\n']).is_err() { + return false; + } + true + } else { + false + } +} diff --git a/packages/liveview/src/hot_reload.rs b/packages/liveview/src/hot_reload.rs index 8385879e0..17a8142c4 100644 --- a/packages/liveview/src/hot_reload.rs +++ b/packages/liveview/src/hot_reload.rs @@ -17,7 +17,9 @@ pub(crate) fn init(proxy: UnboundedSender>) { Ok(_) => { let template: Template<'static> = serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap(); - proxy.send(template).unwrap(); + if proxy.send(template).is_err() { + return; + } } Err(err) => { if err.kind() != std::io::ErrorKind::WouldBlock {