Clone in a terminal:
Commit 9c53342
Johan Mattsson - 2026-07-12T11:36:51+00:00
9c533425fa840bacd7b08cf302a2ab9205245296johan.mattsson.m@gmail.com

Web worker test

Changed files (5)

Diff

diff --git a/Cargo.toml b/Cargo.tomlindex 3c43db6..965b10a 100644--- a/Cargo.toml+++ b/Cargo.toml@@ -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"diff --git a/examples/threads/src/thread.rs b/examples/threads/src/thread.rsindex 31741fd..0933eda 100644--- a/examples/threads/src/thread.rs+++ b/examples/threads/src/thread.rs@@ -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);         }diff --git a/examples/threads2/src/thread.rs b/examples/threads2/src/thread.rsindex 31741fd..0933eda 100644--- a/examples/threads2/src/thread.rs+++ b/examples/threads2/src/thread.rs@@ -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);         }diff --git a/src/lib.rs b/src/lib.rsindex aabe35d..2d0dae5 100644--- a/src/lib.rs+++ b/src/lib.rs@@ -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. ///diff --git a/src/prelude.rs b/src/prelude.rsindex e4bf4b5..f195551 100644--- a/src/prelude.rs+++ b/src/prelude.rs@@ -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;

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112