From d89ab3cfad59d8c66a3acb7ae2aae3e904f23a3a Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 10 Dec 2024 18:47:51 -0600 Subject: [PATCH] Always run toast eval inside the runtime (#3313) --- packages/web/src/devtools.rs | 24 ++++++++++++++++++++---- packages/web/src/lib.rs | 6 +++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/web/src/devtools.rs b/packages/web/src/devtools.rs index 9a56cb3fa8..2ea92b91d7 100644 --- a/packages/web/src/devtools.rs +++ b/packages/web/src/devtools.rs @@ -4,9 +4,11 @@ //! We also set up a little recursive timer that will attempt to reconnect if the connection is lost. use std::fmt::Display; +use std::rc::Rc; use std::time::Duration; -use dioxus_core::ScopeId; +use dioxus_core::prelude::RuntimeGuard; +use dioxus_core::{Runtime, ScopeId}; use dioxus_devtools::{DevserverMsg, HotReloadMsg}; use dioxus_document::eval; use futures_channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; @@ -22,17 +24,22 @@ const POLL_INTERVAL_SCALE_FACTOR: i32 = 2; /// Amount of time that toats should be displayed. const TOAST_TIMEOUT: Duration = Duration::from_secs(5); -pub(crate) fn init() -> UnboundedReceiver { +pub(crate) fn init(runtime: Rc) -> UnboundedReceiver { // Create the tx/rx pair that we'll use for the top-level future in the dioxus loop let (tx, rx) = unbounded(); // Wire up the websocket to the devserver - make_ws(tx, POLL_INTERVAL_MIN, false); + make_ws(runtime, tx, POLL_INTERVAL_MIN, false); rx } -fn make_ws(tx: UnboundedSender, poll_interval: i32, reload: bool) { +fn make_ws( + runtime: Rc, + tx: UnboundedSender, + poll_interval: i32, + reload: bool, +) { // Get the location of the devserver, using the current location plus the /_dioxus path // The idea here being that the devserver is always located on the /_dioxus behind a proxy let location = web_sys::window().unwrap().location(); @@ -49,6 +56,7 @@ fn make_ws(tx: UnboundedSender, poll_interval: i32, reload: bool) // Set the onmessage handler to bounce messages off to the main dioxus loop let tx_ = tx.clone(); + let runtime_ = runtime.clone(); ws.set_onmessage(Some( Closure::::new(move |e: MessageEvent| { let Ok(text) = e.data().dyn_into::() else { @@ -72,6 +80,7 @@ fn make_ws(tx: UnboundedSender, poll_interval: i32, reload: bool) // The devserver is telling us that it started a full rebuild. This does not mean that it is ready. Ok(DevserverMsg::FullReloadStart) => show_toast( + runtime_.clone(), "Your app is being rebuilt.", "A non-hot-reloadable change occurred and we must rebuild.", ToastLevel::Info, @@ -80,6 +89,7 @@ fn make_ws(tx: UnboundedSender, poll_interval: i32, reload: bool) ), // The devserver is telling us that the full rebuild failed. Ok(DevserverMsg::FullReloadFailed) => show_toast( + runtime_.clone(), "Oops! The build failed.", "We tried to rebuild your app, but something went wrong.", ToastLevel::Error, @@ -90,6 +100,7 @@ fn make_ws(tx: UnboundedSender, poll_interval: i32, reload: bool) // The devserver is telling us to reload the whole page Ok(DevserverMsg::FullReloadCommand) => { show_toast( + runtime_.clone(), "Successfully rebuilt.", "Your app was rebuilt successfully and without error.", ToastLevel::Success, @@ -121,11 +132,13 @@ fn make_ws(tx: UnboundedSender, poll_interval: i32, reload: bool) // set timeout to reload the page in timeout_ms let tx = tx.clone(); + let runtime = runtime.clone(); web_sys::window() .unwrap() .set_timeout_with_callback_and_timeout_and_arguments_0( Closure::::new(move || { make_ws( + runtime.clone(), tx.clone(), POLL_INTERVAL_MAX.min(poll_interval * POLL_INTERVAL_SCALE_FACTOR), true, @@ -189,6 +202,7 @@ impl Display for ToastLevel { /// Displays a toast to the developer. fn show_toast( + runtime: Rc, header_text: &str, message: &str, level: ToastLevel, @@ -202,6 +216,8 @@ fn show_toast( false => "showDXToast", }; + // Create the guard before running eval which uses the global runtime context + let _guard = RuntimeGuard::new(runtime); ScopeId::ROOT.in_runtime(|| { eval(&format!( r#" diff --git a/packages/web/src/lib.rs b/packages/web/src/lib.rs index 11071d8910..b26bcd3e04 100644 --- a/packages/web/src/lib.rs +++ b/packages/web/src/lib.rs @@ -66,11 +66,11 @@ pub async fn run(mut virtual_dom: VirtualDom, web_config: Config) -> ! { #[cfg(feature = "document")] virtual_dom.in_runtime(document::init_document); - #[cfg(all(feature = "devtools", debug_assertions))] - let mut hotreload_rx = devtools::init(); - let runtime = virtual_dom.runtime(); + #[cfg(all(feature = "devtools", debug_assertions))] + let mut hotreload_rx = devtools::init(runtime.clone()); + let should_hydrate = web_config.hydrate; let mut websys_dom = WebsysDom::new(web_config, runtime);