diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index df53bfaff..daf94e0ec 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -74,9 +74,9 @@ pub(crate) mod innerlude { pub use crate::innerlude::{ fc_to_builder, generation, once, schedule_update, schedule_update_any, vdom_is_rendering, AnyValue, Attribute, AttributeValue, CapturedError, Component, DynamicNode, Element, ElementId, - Event, Fragment, IntoDynNode, Mutation, MutationsVec, Properties, ScopeId, Task, Template, - TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, VPlaceholder, VText, - VirtualDom, WriteMutations, + Event, Fragment, IntoDynNode, Mutation, MutationsVec, NoOpMutations, Properties, RenderReturn, + ScopeId, Task, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, + VPlaceholder, VText, VirtualDom, WriteMutations, }; /// The purpose of this module is to alleviate imports of many common types diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 3bef82f4a..72b03995b 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -1,7 +1,7 @@ use crate::any_props::{BoxedAnyProps, VProps}; -use crate::innerlude::{ElementRef, EventHandler, MountId}; -use crate::Properties; +use crate::innerlude::{ElementRef, EventHandler, MountId, ScopeState}; use crate::{arena::ElementId, Element, Event}; +use crate::{Properties, VirtualDom}; use std::ops::Deref; use std::rc::Rc; use std::vec; @@ -20,7 +20,7 @@ pub type TemplateId = &'static str; /// /// Dioxus will do its best to immediately resolve any async components into a regular Element, but as an implementor /// you might need to handle the case where there's no node immediately ready. -pub(crate) enum RenderReturn { +pub enum RenderReturn { /// A currently-available element Ready(VNode), @@ -476,6 +476,24 @@ impl VComponent { props: BoxedAnyProps::new(vcomp), } } + + /// Get the scope this node is mounted to if it's mounted + /// + /// This is useful for rendering nodes outside of the VirtualDom, such as in SSR + /// + /// Returns [`None`] if the node is not mounted + pub fn mounted_scope<'a>( + &self, + dynamic_node_index: usize, + vnode: &VNode, + dom: &'a VirtualDom, + ) -> Option<&'a ScopeState> { + let mount = vnode.mount.get().as_usize()?; + + let scope_id = dom.mounts.get(mount)?.mounted_dynamic_nodes[dynamic_node_index]; + + dom.scopes.get(scope_id) + } } impl std::fmt::Debug for VComponent { diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index b15b6cc65..fa3ebd45c 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -27,10 +27,10 @@ impl ScopeId { pub const ROOT: ScopeId = ScopeId(0); } -/// A component's state separate from its props. +/// A component's rendered state. /// -/// This struct exists to provide a common interface for all scopes without relying on generics. -pub(crate) struct ScopeState { +/// This state erases the type of the component's props. It is used to store the state of a component in the runtime. +pub struct ScopeState { pub(crate) runtime: Rc, pub(crate) context_id: ScopeId, diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 7302c58ef..4e3b3e69e 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -293,7 +293,7 @@ impl VirtualDom { /// Get the state for any scope given its ID /// /// This is useful for inserting or removing contexts from a scope, or rendering out its root node - pub(crate) fn get_scope(&self, id: ScopeId) -> Option<&ScopeState> { + pub fn get_scope(&self, id: ScopeId) -> Option<&ScopeState> { self.scopes.get(id.0) } diff --git a/packages/core/tests/diff_keyed_list.rs b/packages/core/tests/diff_keyed_list.rs index ed14c2d95..2e4604ceb 100644 --- a/packages/core/tests/diff_keyed_list.rs +++ b/packages/core/tests/diff_keyed_list.rs @@ -62,7 +62,7 @@ fn keyed_diffing_out_of_order_adds() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -88,7 +88,7 @@ fn keyed_diffing_out_of_order_adds_3() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -114,7 +114,7 @@ fn keyed_diffing_out_of_order_adds_4() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -140,7 +140,7 @@ fn keyed_diffing_out_of_order_adds_5() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -165,7 +165,7 @@ fn keyed_diffing_additions() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -190,7 +190,7 @@ fn keyed_diffing_additions_and_moves_on_ends() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -219,7 +219,7 @@ fn keyed_diffing_additions_and_moves_in_middle() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); // LIS: 4, 5, 6 dom.mark_dirty(ScopeId::ROOT); @@ -253,7 +253,7 @@ fn controlled_keyed_diffing_out_of_order() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); // LIS: 5, 6 dom.mark_dirty(ScopeId::ROOT); @@ -287,7 +287,7 @@ fn controlled_keyed_diffing_out_of_order_max_test() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -316,7 +316,7 @@ fn remove_list() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( @@ -341,7 +341,7 @@ fn no_common_keys() { cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" })))) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); assert_eq!( diff --git a/packages/core/tests/diff_unkeyed_list.rs b/packages/core/tests/diff_unkeyed_list.rs index b5be161ef..3c594ac44 100644 --- a/packages/core/tests/diff_unkeyed_list.rs +++ b/packages/core/tests/diff_unkeyed_list.rs @@ -282,7 +282,7 @@ fn two_equal_fragments_are_equal_static() { }) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert!(dom.render_immediate().edits.is_empty()); } @@ -296,7 +296,7 @@ fn two_equal_fragments_are_equal() { }) }); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert!(dom.render_immediate().edits.is_empty()); } diff --git a/packages/core/tests/error_boundary.rs b/packages/core/tests/error_boundary.rs index 58d861169..c7990f8a4 100644 --- a/packages/core/tests/error_boundary.rs +++ b/packages/core/tests/error_boundary.rs @@ -5,7 +5,7 @@ use dioxus::prelude::*; #[test] fn catches_panic() { let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); } fn app(cx: Scope) -> Element { diff --git a/packages/core/tests/event_propagation.rs b/packages/core/tests/event_propagation.rs index fb87bb16a..a337963d3 100644 --- a/packages/core/tests/event_propagation.rs +++ b/packages/core/tests/event_propagation.rs @@ -9,7 +9,7 @@ fn events_propagate() { set_event_converter(Box::new(dioxus_html::SerializedHtmlEventConverter)); let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); // Top-level click is registered dom.handle_event( diff --git a/packages/core/tests/lifecycle.rs b/packages/core/tests/lifecycle.rs index 6db294653..8a955e620 100644 --- a/packages/core/tests/lifecycle.rs +++ b/packages/core/tests/lifecycle.rs @@ -24,7 +24,7 @@ fn manual_diffing() { let value = Arc::new(Mutex::new("Hello")); let mut dom = VirtualDom::new_with_props(app, AppProps { value: value.clone() }); - let _ = dom.rebuild(); + let _ = dom.rebuild(&mut dioxus_core::NoOpMutations); *value.lock().unwrap() = "goodbye"; @@ -56,7 +56,7 @@ fn events_generate() { }; let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.handle_event( "click", diff --git a/packages/core/tests/miri_full_app.rs b/packages/core/tests/miri_full_app.rs index c285db7d5..44db2f440 100644 --- a/packages/core/tests/miri_full_app.rs +++ b/packages/core/tests/miri_full_app.rs @@ -9,7 +9,7 @@ fn miri_rollover() { set_event_converter(Box::new(SerializedHtmlEventConverter)); let mut dom = VirtualDom::new(App); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); for _ in 0..3 { dom.handle_event( diff --git a/packages/core/tests/miri_simple.rs b/packages/core/tests/miri_simple.rs index 5ad89f4b9..1991d471b 100644 --- a/packages/core/tests/miri_simple.rs +++ b/packages/core/tests/miri_simple.rs @@ -11,7 +11,7 @@ fn app_drops() { let mut dom = VirtualDom::new(App); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); _ = dom.render_immediate(); } @@ -32,7 +32,7 @@ fn hooks_drop() { let mut dom = VirtualDom::new(App); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); _ = dom.render_immediate(); } @@ -61,7 +61,7 @@ fn contexts_drop() { let mut dom = VirtualDom::new(App); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); _ = dom.render_immediate(); } @@ -81,7 +81,7 @@ fn tasks_drop() { let mut dom = VirtualDom::new(App); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); _ = dom.render_immediate(); } @@ -95,7 +95,7 @@ fn root_props_drop() { RootProps("asdasd".to_string()), ); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); _ = dom.render_immediate(); } @@ -126,7 +126,7 @@ fn diffing_drops_old() { } let mut dom = VirtualDom::new(App); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.mark_dirty(ScopeId::ROOT); _ = dom.render_immediate(); diff --git a/packages/core/tests/miri_stress.rs b/packages/core/tests/miri_stress.rs index ff8d69788..396cef36c 100644 --- a/packages/core/tests/miri_stress.rs +++ b/packages/core/tests/miri_stress.rs @@ -59,7 +59,7 @@ fn test_memory_leak() { let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); for _ in 0..5 { dom.mark_dirty(ScopeId::ROOT); @@ -95,7 +95,7 @@ fn memo_works_properly() { let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); // todo!() // dom.hard_diff(ScopeId::ROOT); // dom.hard_diff(ScopeId::ROOT); @@ -127,7 +127,7 @@ fn free_works_on_root_hooks() { let ptr = Rc::new("asdasd".to_string()); let mut dom = VirtualDom::new_with_props(app, AppProps { inner: ptr.clone() }); - let _ = dom.rebuild(); + let _ = dom.rebuild(&mut dioxus_core::NoOpMutations); // ptr gets cloned into props and then into the hook assert_eq!(Rc::strong_count(&ptr), 4); @@ -204,7 +204,7 @@ fn supports_async() { rt.block_on(async { let mut dom = VirtualDom::new(app); - let _ = dom.rebuild(); + let _ = dom.rebuild(&mut dioxus_core::NoOpMutations); for _ in 0..10 { dom.wait_for_work().await; diff --git a/packages/core/tests/suspense.rs b/packages/core/tests/suspense.rs index 1a7ab3d58..c18c66e90 100644 --- a/packages/core/tests/suspense.rs +++ b/packages/core/tests/suspense.rs @@ -9,7 +9,7 @@ fn it_works() { .unwrap() .block_on(async { let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); dom.wait_for_suspense().await; let out = dioxus_ssr::render(&dom); diff --git a/packages/core/tests/task.rs b/packages/core/tests/task.rs index e1ff55c85..db4f1ebb6 100644 --- a/packages/core/tests/task.rs +++ b/packages/core/tests/task.rs @@ -30,7 +30,7 @@ async fn it_works() { let mut dom = VirtualDom::new(app); - let _ = dom.rebuild(); + let _ = dom.rebuild(&mut dioxus_core::NoOpMutations); tokio::select! { _ = dom.wait_for_work() => {} diff --git a/packages/dioxus/benches/jsframework.rs b/packages/dioxus/benches/jsframework.rs index b3405b2bd..5af18fb79 100644 --- a/packages/dioxus/benches/jsframework.rs +++ b/packages/dioxus/benches/jsframework.rs @@ -42,7 +42,7 @@ fn create_rows(c: &mut Criterion) { c.bench_function("create rows", |b| { let mut dom = VirtualDom::new(app); - let _ = dom.rebuild(); + let _ = dom.rebuild(&mut dioxus_core::NoOpMutations); b.iter(|| { let g = dom.rebuild(); diff --git a/packages/dioxus/examples/stress.rs b/packages/dioxus/examples/stress.rs index 248d851d2..2ed1729d4 100644 --- a/packages/dioxus/examples/stress.rs +++ b/packages/dioxus/examples/stress.rs @@ -4,10 +4,10 @@ use rand::prelude::*; fn main() { let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); for _ in 0..1000 { - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); } } diff --git a/packages/ssr/Cargo.toml b/packages/ssr/Cargo.toml index 1a8d475ee..fac0907e1 100644 --- a/packages/ssr/Cargo.toml +++ b/packages/ssr/Cargo.toml @@ -31,6 +31,7 @@ argh = "0.1.4" serde = "1.0.120" serde_json = "1.0.61" fs_extra = "1.2.0" +dioxus-signals.workspace = true [features] default = ["incremental"] diff --git a/packages/ssr/README.md b/packages/ssr/README.md index 59dbfbacf..29dac898e 100644 --- a/packages/ssr/README.md +++ b/packages/ssr/README.md @@ -18,7 +18,7 @@ This crate is a part of the broader Dioxus ecosystem. For more resources about D Dioxus SSR provides utilities to render Dioxus components to valid HTML. Once rendered, the HTML can be rehydrated client-side or served from your web server of choice. ```rust, ignore -let app: Component = |cx| cx.render(rsx!(div {"hello world!"})); +let app: Component = |cx| render!(div {"hello world!"}); let mut vdom = VirtualDom::new(app); let _ = vdom.rebuild(); @@ -29,12 +29,12 @@ assert_eq!(text, "
hello world!
") ## Basic Usage -The simplest example is to simply render some `rsx!` nodes to HTML. This can be done with the [`render_lazy`] API. +The simplest example is to simply render some `render!` nodes to HTML. This can be done with the [`render_element`] API. ```rust, ignore -let content = dioxus_ssr::render_lazy(rsx!{ +let content = dioxus_ssr::render_element(render!{ div { - (0..5).map(|i| rsx!( + (0..5).map(|i| render!( "Number: {i}" )) } @@ -84,19 +84,19 @@ The rest of the space - IE doing this more efficiently, caching the VirtualDom, ## Usage without a VirtualDom -Dioxus SSR needs an arena to allocate from - whether it be the VirtualDom or a dedicated Bump allocator. To render `rsx!` directly to a string, you'll want to create a `Renderer` and call `render_lazy`. +Dioxus SSR needs an arena to allocate from - whether it be the VirtualDom or a dedicated Bump allocator. To render `render!` directly to a string, you'll want to create a `Renderer` and call `render_element`. ```rust, ignore -let text = dioxus_ssr::Renderer::new().render_lazy(rsx!{ +let text = dioxus_ssr::Renderer::new().render_element(render!{ div { "hello world" } }); assert_eq!(text, "
hello world!
") ``` -This can be automated with the `render_lazy!` macro: +This can be automated with the `render_element!` macro: ```rust, ignore -let text = render_lazy!(rsx!( div { "hello world" } )); +let text = render_element!(render!( div { "hello world" } )); ``` ## Usage in static site generation diff --git a/packages/ssr/src/lib.rs b/packages/ssr/src/lib.rs index 09b795f72..e5b0e5e04 100644 --- a/packages/ssr/src/lib.rs +++ b/packages/ssr/src/lib.rs @@ -14,6 +14,7 @@ pub mod eval; pub mod renderer; pub mod template; +use dioxus_core::NoOpMutations; use dioxus_core::{Element, VirtualDom}; pub use crate::renderer::Renderer; @@ -28,7 +29,7 @@ pub fn render_element(element: Element) -> String { let mut dom = VirtualDom::new_with_props(lazy_app, element); dom.in_runtime(crate::eval::init_eval); - _ = dom.rebuild(&mut NoOpMutations); + dom.rebuild(&mut NoOpMutations); Renderer::new().render(&dom) } diff --git a/packages/ssr/src/renderer.rs b/packages/ssr/src/renderer.rs index 1c77a3a7b..6b5f012c0 100644 --- a/packages/ssr/src/renderer.rs +++ b/packages/ssr/src/renderer.rs @@ -1,5 +1,6 @@ use super::cache::Segment; use crate::cache::StringCache; +use dioxus_core::RenderReturn; use dioxus_core::Attribute; use dioxus_core::{prelude::*, AttributeValue, DynamicNode}; @@ -118,8 +119,7 @@ impl Renderer { if self.skip_components { write!(buf, "<{}><{}/>", node.name, node.name)?; } else { - let id = node.mounted_scope().unwrap(); - let scope = dom.get_scope(id).unwrap(); + let scope = node.mounted_scope(*idx, template, dom).unwrap(); let node = scope.root_node(); match node { RenderReturn::Ready(node) => { @@ -227,7 +227,7 @@ impl Renderer { fn to_string_works() { use dioxus::prelude::*; - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { let dynamic = 123; let dyn2 = ""; // this should be escaped @@ -240,13 +240,13 @@ fn to_string_works() { div {} div { "nest 2" } "{dyn2}" - (0..5).map(|i| rsx! { div { "finalize {i}" } }) + (0..5).map(|i| render! { div { "finalize {i}" } }) } } } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); let mut renderer = Renderer::new(); let out = renderer.render(&dom); @@ -285,7 +285,7 @@ fn to_string_works() { fn empty_for_loop_works() { use dioxus::prelude::*; - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { div { class: "asdasdasd", for _ in (0..5) { @@ -296,7 +296,7 @@ fn empty_for_loop_works() { } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); let mut renderer = Renderer::new(); let out = renderer.render(&dom); @@ -328,35 +328,12 @@ fn empty_for_loop_works() { fn empty_render_works() { use dioxus::prelude::*; - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! {} } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); - - let mut renderer = Renderer::new(); - let out = renderer.render(&dom); - - for item in renderer.template_cache.iter() { - if item.1.segments.len() > 5 { - assert_eq!(item.1.segments, vec![]); - } - } - assert_eq!(out, ""); -} - -#[test] -fn empty_rsx_works() { - use dioxus::prelude::*; - - fn app(_: Scope) -> Element { - rsx! {}; - None - } - - let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); let mut renderer = Renderer::new(); let out = renderer.render(&dom); @@ -415,7 +392,7 @@ pub(crate) fn truthy(value: &AttributeValue) -> bool { pub(crate) fn write_attribute(buf: &mut impl Write, attr: &Attribute) -> std::fmt::Result { let name = &attr.name; - match attr.value { + match &attr.value { AttributeValue::Text(value) => write!(buf, " {name}=\"{value}\""), AttributeValue::Bool(value) => write!(buf, " {name}={value}"), AttributeValue::Int(value) => write!(buf, " {name}={value}"), diff --git a/packages/ssr/tests/bool_attr.rs b/packages/ssr/tests/bool_attr.rs index 778e90dcc..7d67943df 100644 --- a/packages/ssr/tests/bool_attr.rs +++ b/packages/ssr/tests/bool_attr.rs @@ -2,7 +2,7 @@ use dioxus::prelude::*; #[test] fn static_boolean_attributs() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { div { hidden: "false" } div { hidden: "true" } @@ -10,7 +10,7 @@ fn static_boolean_attributs() { } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::render(&dom), @@ -20,7 +20,7 @@ fn static_boolean_attributs() { #[test] fn dynamic_boolean_attributs() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { div { hidden: false } div { hidden: true } @@ -28,7 +28,7 @@ fn dynamic_boolean_attributs() { } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::render(&dom), diff --git a/packages/ssr/tests/hydration.rs b/packages/ssr/tests/hydration.rs index 8c9e9f5c8..27c3743bc 100644 --- a/packages/ssr/tests/hydration.rs +++ b/packages/ssr/tests/hydration.rs @@ -2,12 +2,12 @@ use dioxus::prelude::*; #[test] fn root_ids() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { div { width: "100px" } } } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), @@ -17,7 +17,7 @@ fn root_ids() { #[test] fn dynamic_attributes() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { let dynamic = 123; render! { div { width: "100px", div { width: "{dynamic}px" } } @@ -25,7 +25,7 @@ fn dynamic_attributes() { } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), @@ -35,21 +35,21 @@ fn dynamic_attributes() { #[test] fn listeners() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { div { width: "100px", div { onclick: |_| {} } } } } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), r#"
"# ); - fn app2(cx: Scope) -> Element { + fn app2(_: ()) -> Element { let dynamic = 123; render! { div { width: "100px", div { width: "{dynamic}px", onclick: |_| {} } } @@ -57,7 +57,7 @@ fn listeners() { } let mut dom = VirtualDom::new(app2); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), @@ -67,7 +67,7 @@ fn listeners() { #[test] fn text_nodes() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { let dynamic_text = "hello"; render! { div { dynamic_text } @@ -75,14 +75,14 @@ fn text_nodes() { } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), r#"
hello
"# ); - fn app2(cx: Scope) -> Element { + fn app2(_: ()) -> Element { let dynamic = 123; render! { div { "{dynamic}", "{1234}" } @@ -90,7 +90,7 @@ fn text_nodes() { } let mut dom = VirtualDom::new(app2); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), @@ -101,27 +101,27 @@ fn text_nodes() { #[allow(non_snake_case)] #[test] fn components_hydrate() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { Child {} } } - fn Child(cx: Scope) -> Element { + fn Child(_: ()) -> Element { render! { div { "hello" } } } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), r#"
hello
"# ); - fn app2(cx: Scope) -> Element { + fn app2(_: ()) -> Element { render! { Child2 {} } } - fn Child2(cx: Scope) -> Element { + fn Child2(_: ()) -> Element { let dyn_text = "hello"; render! { div { dyn_text } @@ -129,34 +129,34 @@ fn components_hydrate() { } let mut dom = VirtualDom::new(app2); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), r#"
hello
"# ); - fn app3(cx: Scope) -> Element { + fn app3(_: ()) -> Element { render! { Child3 {} } } - fn Child3(cx: Scope) -> Element { + fn Child3(_: ()) -> Element { render! { div { width: "{1}" } } } let mut dom = VirtualDom::new(app3); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), r#"
"# ); - fn app4(cx: Scope) -> Element { + fn app4(_: ()) -> Element { render! { Child4 {} } } - fn Child4(cx: Scope) -> Element { + fn Child4(_: ()) -> Element { render! { for _ in 0..2 { render! { @@ -169,7 +169,7 @@ fn components_hydrate() { } let mut dom = VirtualDom::new(app4); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), @@ -179,18 +179,20 @@ fn components_hydrate() { #[test] fn hello_world_hydrates() { - fn app(cx: Scope) -> Element { - let mut count = use_state(cx, || 0); + use dioxus_signals::use_signal; - cx.render(rsx! { + fn app(_: ()) -> Element { + let mut count = use_signal(|| 0); + + render! { h1 { "High-Five counter: {count}" } button { onclick: move |_| count += 1, "Up high!" } button { onclick: move |_| count -= 1, "Down low!" } - }) + } } let mut dom = VirtualDom::new(app); - _ = dbg!(dom.rebuild()); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::pre_render(&dom), diff --git a/packages/ssr/tests/inner_html.rs b/packages/ssr/tests/inner_html.rs index 11fb94746..e884235f0 100644 --- a/packages/ssr/tests/inner_html.rs +++ b/packages/ssr/tests/inner_html.rs @@ -2,25 +2,25 @@ use dioxus::prelude::*; #[test] fn static_inner_html() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { div { dangerous_inner_html: "
1234
" } } } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!(dioxus_ssr::render(&dom), r#"
1234
"#); } #[test] fn dynamic_inner_html() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { let inner_html = "
1234
"; render! { div { dangerous_inner_html: "{inner_html}" } } } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!(dioxus_ssr::render(&dom), r#"
1234
"#); } diff --git a/packages/ssr/tests/simple.rs b/packages/ssr/tests/simple.rs index a9034df9b..8449e97a0 100644 --- a/packages/ssr/tests/simple.rs +++ b/packages/ssr/tests/simple.rs @@ -2,18 +2,17 @@ use dioxus::prelude::*; #[test] fn simple() { - #[component] - fn App(cx: Scope) -> Element { + fn App(_: ()) -> Element { render! { div { "hello!" } } } let mut dom = VirtualDom::new(App); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!(dioxus_ssr::render(&dom), "
hello!
"); assert_eq!( - dioxus_ssr::render_lazy(rsx!( div {"hello!"} )), + dioxus_ssr::render_element(render!( div {"hello!"} )), "
hello!
" ); } @@ -21,9 +20,9 @@ fn simple() { #[test] fn lists() { assert_eq!( - dioxus_ssr::render_lazy(rsx! { + dioxus_ssr::render_element(render! { ul { - (0..5).map(|i| rsx! { + (0..5).map(|i| render! { li { "item {i}" } }) } @@ -36,7 +35,7 @@ fn lists() { fn dynamic() { let dynamic = 123; assert_eq!( - dioxus_ssr::render_lazy(rsx! { + dioxus_ssr::render_element(render! { div { "Hello world 1 -->" "{dynamic}" "<-- Hello world 2" } }), "
Hello world 1 -->123<-- Hello world 2
" @@ -45,15 +44,19 @@ fn dynamic() { #[test] fn components() { - #[component] - fn MyComponent(cx: Scope, name: i32) -> Element { + #[derive(Props, Clone, PartialEq)] + struct MyComponentProps { + name: i32, + } + + fn MyComponent(MyComponentProps { name }: MyComponentProps) -> Element { render! { div { "component {name}" } } } assert_eq!( - dioxus_ssr::render_lazy(rsx! { + dioxus_ssr::render_element(render! { div { - (0..5).map(|name| rsx! { + (0..5).map(|name| render! { MyComponent { name: name } }) } @@ -65,9 +68,9 @@ fn components() { #[test] fn fragments() { assert_eq!( - dioxus_ssr::render_lazy(rsx! { + dioxus_ssr::render_element(render! { div { - (0..5).map(|_| rsx! (())) + (0..5).map(|_| render! (())) } }), "
" diff --git a/packages/ssr/tests/styles.rs b/packages/ssr/tests/styles.rs index de77e715c..9f66e2e92 100644 --- a/packages/ssr/tests/styles.rs +++ b/packages/ssr/tests/styles.rs @@ -2,12 +2,12 @@ use dioxus::prelude::*; #[test] fn static_styles() { - fn app(cx: Scope) -> Element { + fn app(_: ()) -> Element { render! { div { width: "100px" } } } let mut dom = VirtualDom::new(app); - _ = dom.rebuild(); + _ = dom.rebuild(&mut dioxus_core::NoOpMutations); assert_eq!( dioxus_ssr::render(&dom), @@ -20,7 +20,7 @@ fn partially_dynamic_styles() { let dynamic = 123; assert_eq!( - dioxus_ssr::render_lazy(rsx! { + dioxus_ssr::render_element(render! { div { width: "100px", height: "{dynamic}px" } }), r#"
"# @@ -32,7 +32,7 @@ fn dynamic_styles() { let dynamic = 123; assert_eq!( - dioxus_ssr::render_lazy(rsx! { + dioxus_ssr::render_element(render! { div { width: "{dynamic}px" } }), r#"
"# diff --git a/packages/web/examples/hydrate.rs b/packages/web/examples/hydrate.rs index 8a6cd464e..42b1be755 100644 --- a/packages/web/examples/hydrate.rs +++ b/packages/web/examples/hydrate.rs @@ -38,7 +38,7 @@ fn main() { tracing_wasm::set_as_global_default(); let mut dom = VirtualDom::new(app); - let _ = dom.rebuild(); + let _ = dom.rebuild(&mut dioxus_core::NoOpMutations); let pre = dioxus_ssr::pre_render(&dom); tracing::trace!("{}", pre); diff --git a/packages/web/tests/hydrate.rs b/packages/web/tests/hydrate.rs index c7de26a8c..a840722dc 100644 --- a/packages/web/tests/hydrate.rs +++ b/packages/web/tests/hydrate.rs @@ -49,7 +49,7 @@ fn rehydrates() { } let mut dom = VirtualDom::new(app); - let _ = dom.rebuild(); + let _ = dom.rebuild(&mut dioxus_core::NoOpMutations); let out = dioxus_ssr::render(&dom); window()