1use std::{fmt::Debug, sync::Arc};
2
3use bloom_core::{render_loop, Element};
4use bloom_html::HtmlNode;
5use dom::Dom;
6use interned_str::interned;
7use spawner::WasmSpawner;
8use wasm_bindgen_futures::spawn_local;
9use web_sys::{console, wasm_bindgen::JsCast, window, HtmlElement};
10
11mod dom;
12mod interned_str;
13mod partial;
14mod spawner;
15
16pub use partial::hydrate_partial;
17
18pub fn get_element_by_id(id: &str) -> Option<HtmlElement> {
19 window()
20 .and_then(|window| window.document())
21 .and_then(|document| document.get_element_by_id(id))
22 .and_then(|element| element.dyn_into::<HtmlElement>().ok())
23}
24
25pub fn render<E>(root: HtmlElement, element: Element<HtmlNode, E>)
37where
38 E: Send + 'static + Debug,
39{
40 spawn_local(async {
41 let mut dom = Dom::new();
42
43 let root_node = Arc::new(
44 HtmlNode::element(interned(root.tag_name().to_lowercase()))
45 .build()
46 .into(),
47 );
48 dom.register(&root_node, root.into());
49 if let Err(error) = render_loop(root_node, element, WasmSpawner, dom).await {
50 let msg = format!("Render loop error: {:?}", error);
51 console::error_1(&msg.into());
52 }
53 });
54}
55
56pub fn hydrate<E>(root: HtmlElement, element: Element<HtmlNode, E>)
58where
59 E: Send + 'static + Debug,
60{
61 spawn_local(async {
62 let mut dom = Dom::hydrate();
63
64 let root_node = Arc::new(
65 HtmlNode::element(interned(root.tag_name().to_lowercase()))
66 .build()
67 .into(),
68 );
69 dom.register(&root_node, root.into());
70 if let Err(error) = render_loop(root_node, element, WasmSpawner, dom).await {
71 let msg = format!("Render loop error: {:?}", error);
72 console::error_1(&msg.into());
73 }
74 });
75}