Commit cfe5d0c
Update component code
Changed files (13)
modifiedexamples/counter-component/Cargo.lockmodifiedexamples/counter-component/src/counter.rsmodifiedexamples/counter-component/src/lib.rsmodifiedexamples/main-component/Cargo.lockmodifiedexamples/main-component/Cargo.tomlmodifiedexamples/main-component/build.shmodifiedexamples/main-component/dev.shmodifiedexamples/main-component/index.htmldeletedexamples/main-component/main.jsmodifiedexamples/main-component/src/lib.rsmodifiedexamples/main-component/src/main_component.rsmodifiedsrc/lib.rsmodifiedsrc/prelude.rs
Diff
@@ -466,7 +466,7 @@ dependencies = [ [[package]] name = "kaja-web"-version = "1.0.3"+version = "1.0.2" dependencies = [ "gloo", "gloo-console",@@ -1,4 +1,4 @@-use kaja_web::prelude::*;+euse kaja_web::prelude::*; #[component("counter-component")] pub struct Counter {@@ -3,8 +3,6 @@ use kaja_web::prelude::*; mod counter; mod main_component; -- #[wasm_bindgen(start)] pub fn init() { std::panic::set_hook(Box::new(console_error_panic_hook::hook));@@ -560,6 +560,7 @@ dependencies = [ "js-sys", "kaja-html-macro", "kaja-web",+ "kaja-web-component", "serde", "serde-wasm-bindgen 0.5.0", "serde_json",@@ -11,7 +11,8 @@ threads = [] [dependencies] wasm-bindgen = "0.2.122"-kaja-web = { version = "1.0.2", path = "../.." }+kaja-web = { path = "../.." }+kaja-web-component = { path = "../../../kaja-web-component" } js-sys = "0.3" web-sys = { version = "0.3.99", features = ["Element", "HtmlElement", "NodeList", "CustomElementRegistry", "ElementDefinitionOptions"] } gloo = { version = "0.12", features = ["futures"] }@@ -8,5 +8,5 @@ wasm-pack build \ --out-name main cp index.html pkg/-cp main.js pkg/+cp loader.js pkg/ cp styles.css pkg/@@ -8,5 +8,5 @@ wasm-pack build \ --out-name componentexample cp index.html pkg/-cp main.js pkg/+cp loader.js pkg/ cp styles.css pkg/@@ -5,10 +5,11 @@ <link rel="stylesheet" href="styles.css" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Example: Web Components using Kaja Web</title>- <script type="module" src="main.js" defer></script>+ <script type="module" src="loader.js" defer></script> </head> <body> <main-component></main-component>+ <div id="2">Two</div> </body> </html>deleted file mode 100644@@ -1,18 +0,0 @@-let wasmModule;--async function loadWasm() {- try {- const wasmModule = await import("./main.js");- await wasmModule.default("./main_bg.wasm");-- return wasmModule;- } catch (error) {- console.error("Failed to load WASM module:", error);- }-- return null;-}--window.addEventListener("DOMContentLoaded", async () => {- wasmModule = await loadWasm();-});@@ -1,9 +1,15 @@ use kaja_web::prelude::*; +mod main_component;+ #[wasm_bindgen(start)] pub fn init() {+ log!("Starting");+ std::panic::set_hook(Box::new(console_error_panic_hook::hook)); console_error_panic_hook::set_once(); + log!("Init callbacks"); init_callbacks();+ log!("Init complete"); }@@ -1,9 +1,4 @@-use crate::log;-use async_channel::{Receiver, Sender};-use std::collections::HashMap;-use std::sync::{Arc, LazyLock, Mutex, OnceLock, RwLock};-use wasm_bindgen::JsCast;-use wasm_bindgen::prelude::*;+use kaja_web::prelude::*; #[component("main-component")] struct Main {@@ -15,33 +10,44 @@ struct Other { the_number: i32, } +impl Component for Other {}+ impl Component for Main { fn connected(id: &str) {- #[cfg(feature = "threads")]- start_background(id);+ log!("Main connected:", id);+ start_background(&id); } fn update(id: &str) { log!("Main ui_thread_update:", id);- let handle = Self::get_component_arc(id);- let mut component = handle.lock().unwrap(); + let Some(handle) = Self::get_component(id) else {+ error!("Main component not found:", id);+ return;+ };++ let Some(element) = get_element_by_id("2") else {+ error!("Element 2 not found:");+ return;+ };++ log!("Element 2 found");++ let Some(element) = get_element_by_id(id) else {+ error!("Element not found:", id);+ return;+ };++ let mut component = handle.lock().unwrap(); component.test = !component.test;- component.render(id);+ component.render(&element); } } impl Main {- fn render(&self, id: &str) {+ fn render(&self, element: &HtmlElement) { log!("Render Main", self.test);- let element = get_element_by_id(id);- element.inner_text(&self.test.to_string());- }-}--impl Component for Other {- fn ui_thread_update(id: &str) {- log!("Other update:", id);+ element.set_inner_text(&self.test.to_string()); } } @@ -51,7 +57,7 @@ fn start_background(id: &str) { wasm_bindgen_futures::spawn_local(async move { loop {- post_ui_thread_update(component_id.as_str()); // await?+ Main::post_ui_thread_update(component_id.as_str()); gloo_timers::future::TimeoutFuture::new(1000).await; } });@@ -63,7 +69,7 @@ fn start_background(id: &str) { std::thread::spawn(move || { loop {- post_ui_thread_update(component_id.as_str());+ Main::post_ui_thread_update(component_id.as_str()); std::thread::sleep(std::time::Duration::from_secs(1)); } });@@ -9,8 +9,6 @@ use web_sys::{Element, HtmlDocument, HtmlElement, HtmlInputElement, NodeList}; pub mod prelude; -use prelude::*;- pub struct InitFn(pub fn()); inventory::collect!(InitFn); @@ -41,6 +39,12 @@ pub struct CallbackRegistration { inventory::collect!(CallbackRegistration); +pub trait ComponentStorage: Default + Sized {+ fn storage() -> &'static std::sync::RwLock<+ Option<std::collections::HashMap<String, std::sync::Arc<std::sync::Mutex<Self>>>>,+ >;+}+ /// 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. ///@@ -72,7 +76,9 @@ pub fn init_callbacks() { (init.0)(); } + log!("Init component fn kaja-web"); for init in inventory::iter::<InitComponentFn> {+ log!("Run init component fn"); (init.0)(); } }@@ -323,19 +329,24 @@ pub fn get_callback(name: &str) -> Option<js_sys::Function> { } /// HTML Component. See kaja-web-component.-pub trait Component {- fn connected(id: &str) {}- fn disconnected(id: &str) {}+pub trait Component: Default {+ fn connected(_id: &str) {}+ fn disconnected(_id: &str) {}+ fn observed_attributes() -> &'static [&'static str] {+ &[]+ } fn attribute_changed(id: &str, name: &str, _old_value: &str, _new_value: &str) {- log!("Attribute changed but no update handler for ", name);+ log!("Attribute changed but no update handler for ", id, name); }- fn update(id: &str) {}+ fn update(_id: &str) {} } pub fn get_element_by_id(id: &str) -> Option<HtmlElement> {- let selector = format!("#{}", id);- let element = get_element(selector.as_str());- element+ let window = web_sys::window().ok_or(Error).ok()?;+ let document = window.document().ok_or(Error).ok()?;+ let element = document.get_element_by_id(id)?;+ let html_element = element.dyn_into::<HtmlElement>().ok()?;+ Some(html_element) } // Example: let count = get_value!(&id, Counter.field);@@ -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, set_value, try_get_value, try_inner_html, try_inner_text,+ CallbackRegistration, Component, ComponentStorage, 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, set_value, try_get_value, try_inner_html,+ try_inner_text, }; pub use gloo::console::error;