Commit 9c53342
Web worker test
Changed files (5)
modifiedCargo.tomlmodifiedexamples/threads/src/thread.rsmodifiedexamples/threads2/src/thread.rsmodifiedsrc/lib.rsmodifiedsrc/prelude.rs
Diff
@@ -15,7 +15,7 @@ gloo = "0.12.0" gloo-console = "0.4.0" kaja-html-macro = "1.0.3" wasm-bindgen = "0.2.122"-web-sys = { version = "0.3.99", features = ["Document", "HtmlDocument", "Element", "HtmlElement", "HtmlInputElement", "NodeList", "CssStyleDeclaration", "DomTokenList"] }+web-sys = { version = "0.3.99", features = ["Document", "HtmlDocument", "Element", "HtmlElement", "HtmlInputElement", "NodeList", "CssStyleDeclaration", "DomTokenList", "MessageEvent"] } serde = { version = "1.0", features = ["derive"] } serde-wasm-bindgen = "0.5" inventory = "0.3.24"@@ -37,7 +37,22 @@ pub fn spawn(f: impl FnOnce() + Send + 'static) -> Result<(), JsValue> { let completion = Closure::<dyn FnMut(_)>::new(move |event: Event| { if let Some(error) = event.dyn_ref::<ErrorEvent>() { console_log!("error in standalone worker: {}", error.message());- } else if event.dyn_ref::<MessageEvent>().is_none() {+ } else if let Some(message) = event.dyn_ref::<MessageEvent>() {+ if kaja_web::try_handle_component_update_message(message) {+ return;+ }++ if message.data().is_undefined() {+ worker2.terminate();+ worker2.set_onmessage(None);+ worker2.set_onerror(None);+ *slot2.borrow_mut() = None;+ return;+ }++ console_log!("unhandled message from standalone worker");+ crate::logv(&message.data());+ } else { console_log!("unhandled event: {}", event.type_()); crate::logv(&event); }@@ -37,7 +37,22 @@ pub fn spawn(f: impl FnOnce() + Send + 'static) -> Result<(), JsValue> { let completion = Closure::<dyn FnMut(_)>::new(move |event: Event| { if let Some(error) = event.dyn_ref::<ErrorEvent>() { console_log!("error in standalone worker: {}", error.message());- } else if event.dyn_ref::<MessageEvent>().is_none() {+ } else if let Some(message) = event.dyn_ref::<MessageEvent>() {+ if kaja_web::try_handle_component_update_message(message) {+ return;+ }++ if message.data().is_undefined() {+ worker2.terminate();+ worker2.set_onmessage(None);+ worker2.set_onerror(None);+ *slot2.borrow_mut() = None;+ return;+ }++ console_log!("unhandled message from standalone worker");+ crate::logv(&message.data());+ } else { console_log!("unhandled event: {}", event.type_()); crate::logv(&event); }@@ -17,6 +17,12 @@ inventory::collect!(InitFn); pub struct InitComponentFn(pub fn()); inventory::collect!(InitComponentFn); +pub struct UpdateComponentFn {+ pub component: &'static str,+ pub dispatch: fn(&str),+}+inventory::collect!(UpdateComponentFn);+ /// Global counter shared by all components created by the #[component] macro. /// The proc-macro-generated code will increment this to obtain a unique wasm id. pub static NEXT_COMPONENT_COUNTER: std::sync::atomic::AtomicU32 =@@ -62,6 +68,50 @@ where next } +pub fn dispatch_component_update(component: &str, id: &str) -> bool {+ for update in inventory::iter::<UpdateComponentFn> {+ if update.component == component {+ (update.dispatch)(id);+ return true;+ }+ }++ false+}++pub fn try_handle_component_update_message(event: &web_sys::MessageEvent) -> bool {+ let Ok(message) = event.data().dyn_into::<js_sys::Array>() else {+ return false;+ };++ if message.length() != 3 {+ return false;+ }++ if message.get(0).as_string().as_deref() != Some("__kaja_component_update__") {+ return false;+ }++ let Some(component) = message.get(1).as_string() else {+ error!("Invalid component update message: missing component name.");+ return true;+ };++ let Some(id) = message.get(2).as_string() else {+ error!(+ "Invalid component update message: missing component id.",+ component+ );+ return true;+ };++ if !dispatch_component_update(&component, &id) {+ error!("Component update handler not found.", component, id);+ }++ true+}+ /// Register callbacks that can be used in JS to run Rust functions in the WASM /// module. This needs to run when the WASM bundle is loaded. ///@@ -1,7 +1,8 @@ pub use crate::{- CallbackRegistration, Component, Error, InitComponentFn, InitFn, Result, get_callback,- get_cookie_value, get_element, get_element_by_id, get_elements, get_value, init_callbacks,- inner_html, inner_text, try_get_value, try_inner_html, try_inner_text,+ CallbackRegistration, Component, Error, InitComponentFn, InitFn, Result, UpdateComponentFn,+ dispatch_component_update, get_callback, get_cookie_value, get_element, get_element_by_id,+ get_elements, get_value, init_callbacks, inner_html, inner_text, try_get_value,+ try_handle_component_update_message, try_inner_html, try_inner_text, update_shared_component, }; pub use gloo::console::error;