mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
removed some HydrationCtx things and improved tracing for DynChild
This commit is contained in:
parent
3b99d2d4fd
commit
422233eecf
4 changed files with 70 additions and 81 deletions
|
@ -151,8 +151,6 @@ where
|
||||||
move |prev_run: Option<(Option<web_sys::Node>, ScopeDisposer)>| {
|
move |prev_run: Option<(Option<web_sys::Node>, ScopeDisposer)>| {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let _guard = span.enter();
|
let _guard = span.enter();
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
let _guard = trace_span!("DynChild reactive").entered();
|
|
||||||
|
|
||||||
let (new_child, disposer) =
|
let (new_child, disposer) =
|
||||||
cx.run_child_scope(|cx| child_fn().into_view(cx));
|
cx.run_child_scope(|cx| child_fn().into_view(cx));
|
||||||
|
|
|
@ -56,18 +56,6 @@ impl HydrationCtx {
|
||||||
unsafe { ID = id }
|
unsafe { ID = id }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
|
||||||
pub(crate) fn set_id(cx: Scope) {
|
|
||||||
/* let new_id = if let Some(id) = cx.get_hydration_key() {
|
|
||||||
id + 1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}; */
|
|
||||||
let new_id = 0;
|
|
||||||
println!("setting ID to {new_id}");
|
|
||||||
unsafe { ID = new_id };
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||||
pub(crate) fn stop_hydrating() {
|
pub(crate) fn stop_hydrating() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//! The DOM implementation for `leptos`.
|
//! The DOM implementation for `leptos`.
|
||||||
|
|
||||||
#[cfg_attr(debug_assertions, macro_use)]
|
#[cfg_attr(debug_assertions, macro_use)]
|
||||||
extern crate tracing;
|
pub extern crate tracing;
|
||||||
|
|
||||||
mod components;
|
mod components;
|
||||||
mod events;
|
mod events;
|
||||||
|
@ -19,7 +19,6 @@ mod node_ref;
|
||||||
mod ssr;
|
mod ssr;
|
||||||
mod transparent;
|
mod transparent;
|
||||||
|
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
pub use components::*;
|
pub use components::*;
|
||||||
pub use events::typed as ev;
|
pub use events::typed as ev;
|
||||||
|
@ -29,7 +28,7 @@ pub use hydration::HydrationCtx;
|
||||||
pub use js_sys;
|
pub use js_sys;
|
||||||
use leptos_reactive::Scope;
|
use leptos_reactive::Scope;
|
||||||
pub use logging::*;
|
pub use logging::*;
|
||||||
pub use macro_helpers::{IntoClass, IntoAttribute, IntoProperty};
|
pub use macro_helpers::{IntoAttribute, IntoClass, IntoProperty};
|
||||||
pub use node_ref::*;
|
pub use node_ref::*;
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -109,7 +108,7 @@ where
|
||||||
{
|
{
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
debug_assertions,
|
debug_assertions,
|
||||||
instrument(level = "trace", name = "Fn() -> N", skip_all)
|
instrument(level = "trace", name = "Fn() -> impl IntoView", skip_all)
|
||||||
)]
|
)]
|
||||||
fn into_view(self, cx: Scope) -> View {
|
fn into_view(self, cx: Scope) -> View {
|
||||||
DynChild::new(self).into_view(cx)
|
DynChild::new(self).into_view(cx)
|
||||||
|
@ -206,7 +205,7 @@ impl Element {
|
||||||
attrs,
|
attrs,
|
||||||
children,
|
children,
|
||||||
id,
|
id,
|
||||||
prerendered
|
prerendered,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let element = AnyElement { name, is_void, id };
|
let element = AnyElement { name, is_void, id };
|
||||||
|
@ -216,7 +215,7 @@ impl Element {
|
||||||
element,
|
element,
|
||||||
attrs,
|
attrs,
|
||||||
children: children.into_iter().collect(),
|
children: children.into_iter().collect(),
|
||||||
prerendered
|
prerendered,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,14 +254,17 @@ impl Element {
|
||||||
|
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn from_html<El: IntoElement>(el: El, html: impl Into<Cow<'static, str>>) -> Self {
|
fn from_html<El: IntoElement>(
|
||||||
|
el: El,
|
||||||
|
html: impl Into<Cow<'static, str>>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: el.name(),
|
name: el.name(),
|
||||||
is_void: el.is_void(),
|
is_void: el.is_void(),
|
||||||
attrs: Default::default(),
|
attrs: Default::default(),
|
||||||
children: Default::default(),
|
children: Default::default(),
|
||||||
id: el.hydration_id(),
|
id: el.hydration_id(),
|
||||||
prerendered: Some(html.into())
|
prerendered: Some(html.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
|
|
||||||
use crate::{CoreComponent, HydrationCtx, IntoView, View};
|
use crate::{CoreComponent, HydrationCtx, IntoView, View};
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use futures::{Stream, StreamExt, stream::FuturesUnordered};
|
use futures::{stream::FuturesUnordered, Stream, StreamExt};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::borrow::Cow;
|
|
||||||
use leptos_reactive::*;
|
use leptos_reactive::*;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
|
||||||
/// Renders the given function to a static HTML string.
|
/// Renders the given function to a static HTML string.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -23,12 +22,17 @@ pub fn render_to_string<F, N>(f: F) -> String
|
||||||
where
|
where
|
||||||
F: FnOnce(Scope) -> N + 'static,
|
F: FnOnce(Scope) -> N + 'static,
|
||||||
N: IntoView,
|
N: IntoView,
|
||||||
{
|
{
|
||||||
let runtime = leptos_reactive::create_runtime();
|
let runtime = leptos_reactive::create_runtime();
|
||||||
HydrationCtx::reset_id();
|
HydrationCtx::reset_id();
|
||||||
let html = leptos_reactive::run_scope(runtime, |cx| f(cx).into_view(cx).render_to_string(cx));
|
|
||||||
runtime.dispose();
|
let html = leptos_reactive::run_scope(runtime, |cx| {
|
||||||
html.into_owned()
|
f(cx).into_view(cx).render_to_string(cx)
|
||||||
|
});
|
||||||
|
|
||||||
|
runtime.dispose();
|
||||||
|
|
||||||
|
html.into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders a function to a stream of HTML strings.
|
/// Renders a function to a stream of HTML strings.
|
||||||
|
@ -43,7 +47,9 @@ where
|
||||||
/// it is waiting for a resource to resolve from the server, it doesn't run it initially.
|
/// it is waiting for a resource to resolve from the server, it doesn't run it initially.
|
||||||
/// 3) HTML fragments to replace each `<Suspense/>` fallback with its actual data as the resources
|
/// 3) HTML fragments to replace each `<Suspense/>` fallback with its actual data as the resources
|
||||||
/// read under that `<Suspense/>` resolve.
|
/// read under that `<Suspense/>` resolve.
|
||||||
pub fn render_to_stream(view: impl FnOnce(Scope) -> View + 'static) -> impl Stream<Item = String> {
|
pub fn render_to_stream(
|
||||||
|
view: impl FnOnce(Scope) -> View + 'static,
|
||||||
|
) -> impl Stream<Item = String> {
|
||||||
render_to_stream_with_prefix(view, |_| "".into())
|
render_to_stream_with_prefix(view, |_| "".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,44 +69,47 @@ pub fn render_to_stream(view: impl FnOnce(Scope) -> View + 'static) -> impl Stre
|
||||||
/// read under that `<Suspense/>` resolve.
|
/// read under that `<Suspense/>` resolve.
|
||||||
pub fn render_to_stream_with_prefix(
|
pub fn render_to_stream_with_prefix(
|
||||||
view: impl FnOnce(Scope) -> View + 'static,
|
view: impl FnOnce(Scope) -> View + 'static,
|
||||||
prefix: impl FnOnce(Scope) -> Cow<'static, str> + 'static
|
prefix: impl FnOnce(Scope) -> Cow<'static, str> + 'static,
|
||||||
) -> impl Stream<Item = String> {
|
) -> impl Stream<Item = String> {
|
||||||
HydrationCtx::reset_id();
|
HydrationCtx::reset_id();
|
||||||
|
|
||||||
// create the runtime
|
// create the runtime
|
||||||
let runtime = create_runtime();
|
let runtime = create_runtime();
|
||||||
|
|
||||||
let ((shell, prefix, pending_resources, pending_fragments, serializers), _, disposer) =
|
let (
|
||||||
run_scope_undisposed(runtime, {
|
(shell, prefix, pending_resources, pending_fragments, serializers),
|
||||||
move |cx| {
|
_,
|
||||||
// the actual app body/template code
|
disposer,
|
||||||
// this does NOT contain any of the data being loaded asynchronously in resources
|
) = run_scope_undisposed(runtime, {
|
||||||
let shell = view(cx).render_to_string(cx);
|
move |cx| {
|
||||||
|
// the actual app body/template code
|
||||||
|
// this does NOT contain any of the data being loaded asynchronously in resources
|
||||||
|
let shell = view(cx).render_to_string(cx);
|
||||||
|
|
||||||
let resources = cx.all_resources();
|
let resources = cx.all_resources();
|
||||||
let pending_resources = serde_json::to_string(&resources).unwrap();
|
let pending_resources = serde_json::to_string(&resources).unwrap();
|
||||||
let prefix = prefix(cx);
|
let prefix = prefix(cx);
|
||||||
|
|
||||||
(
|
(
|
||||||
shell,
|
shell,
|
||||||
prefix,
|
prefix,
|
||||||
pending_resources,
|
pending_resources,
|
||||||
cx.pending_fragments(),
|
cx.pending_fragments(),
|
||||||
cx.serialization_resolvers(),
|
cx.serialization_resolvers(),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let fragments = FuturesUnordered::new();
|
|
||||||
for (fragment_id, fut) in pending_fragments {
|
|
||||||
fragments.push(async move { (fragment_id, fut.await) })
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let fragments = FuturesUnordered::new();
|
||||||
|
for (fragment_id, fut) in pending_fragments {
|
||||||
|
fragments.push(async move { (fragment_id, fut.await) })
|
||||||
|
}
|
||||||
|
|
||||||
// resources and fragments
|
// resources and fragments
|
||||||
// stream HTML for each <Suspense/> as it resolves
|
// stream HTML for each <Suspense/> as it resolves
|
||||||
let fragments = fragments.map(|(fragment_id, html)| {
|
let fragments = fragments.map(|(fragment_id, html)| {
|
||||||
format!(
|
format!(
|
||||||
r#"
|
r#"
|
||||||
<template id="{fragment_id}f">{html}</template>
|
<template id="{fragment_id}f">{html}</template>
|
||||||
<script>
|
<script>
|
||||||
var frag = document.getElementById("{fragment_id}");
|
var frag = document.getElementById("{fragment_id}");
|
||||||
|
@ -108,27 +117,26 @@ pub fn render_to_stream_with_prefix(
|
||||||
if(frag) frag.replaceWith(tpl.content.cloneNode(true));
|
if(frag) frag.replaceWith(tpl.content.cloneNode(true));
|
||||||
</script>
|
</script>
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
// stream data for each Resource as it resolves
|
// stream data for each Resource as it resolves
|
||||||
let resources =
|
let resources = serializers.map(|(id, json)| {
|
||||||
serializers.map(|(id, json)| {
|
let id = serde_json::to_string(&id).unwrap();
|
||||||
let id = serde_json::to_string(&id).unwrap();
|
format!(
|
||||||
format!(
|
r#"<script>
|
||||||
r#"<script>
|
|
||||||
if(__LEPTOS_RESOURCE_RESOLVERS.get({id})) {{
|
if(__LEPTOS_RESOURCE_RESOLVERS.get({id})) {{
|
||||||
__LEPTOS_RESOURCE_RESOLVERS.get({id})({json:?})
|
__LEPTOS_RESOURCE_RESOLVERS.get({id})({json:?})
|
||||||
}} else {{
|
}} else {{
|
||||||
__LEPTOS_RESOLVED_RESOURCES.set({id}, {json:?});
|
__LEPTOS_RESOLVED_RESOURCES.set({id}, {json:?});
|
||||||
}}
|
}}
|
||||||
</script>"#,
|
</script>"#,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// HTML for the view function and script to store resources
|
// HTML for the view function and script to store resources
|
||||||
futures::stream::once(async move {
|
futures::stream::once(async move {
|
||||||
format!(
|
format!(
|
||||||
r#"
|
r#"
|
||||||
{prefix}
|
{prefix}
|
||||||
{shell}
|
{shell}
|
||||||
<script>
|
<script>
|
||||||
|
@ -137,7 +145,7 @@ pub fn render_to_stream_with_prefix(
|
||||||
__LEPTOS_RESOURCE_RESOLVERS = new Map();
|
__LEPTOS_RESOURCE_RESOLVERS = new Map();
|
||||||
</script>
|
</script>
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
// TODO these should be combined again in a way that chains them appropriately
|
// TODO these should be combined again in a way that chains them appropriately
|
||||||
// such that individual resources can resolve before all fragments are done
|
// such that individual resources can resolve before all fragments are done
|
||||||
|
@ -145,23 +153,16 @@ pub fn render_to_stream_with_prefix(
|
||||||
.chain(resources)
|
.chain(resources)
|
||||||
// dispose of Scope and Runtime
|
// dispose of Scope and Runtime
|
||||||
.chain(futures::stream::once(async move {
|
.chain(futures::stream::once(async move {
|
||||||
disposer.dispose();
|
disposer.dispose();
|
||||||
runtime.dispose();
|
runtime.dispose();
|
||||||
Default::default()
|
Default::default()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
/// Consumes the node and renders it into an HTML string.
|
/// Consumes the node and renders it into an HTML string.
|
||||||
pub fn render_to_string(self, cx: Scope) -> Cow<'static, str> {
|
pub fn render_to_string(self, cx: Scope) -> Cow<'static, str> {
|
||||||
//cx.set_hydration_key(HydrationCtx::current_id());
|
self.render_to_string_helper()
|
||||||
HydrationCtx::set_id(cx);
|
|
||||||
|
|
||||||
let s = self.render_to_string_helper();
|
|
||||||
|
|
||||||
//cx.set_hydration_key(HydrationCtx::current_id());
|
|
||||||
|
|
||||||
s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn render_to_string_helper(self) -> Cow<'static, str> {
|
pub(crate) fn render_to_string_helper(self) -> Cow<'static, str> {
|
||||||
|
|
Loading…
Reference in a new issue