Skip to content

Commit

Permalink
fix ssg render template
Browse files Browse the repository at this point in the history
  • Loading branch information
ealmloff committed Jun 6, 2024
1 parent 94d0ace commit ab1d474
Show file tree
Hide file tree
Showing 20 changed files with 59 additions and 245 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ version = "0.5.2"

# dependencies that are shared across packages
[workspace.dependencies]
dioxus = { path = "packages/dioxus", version = "0.5.0" }
dioxus = { path = "packages/dioxus", version = "0.5.0", features = ["minimal"], default-features = false }
dioxus-lib = { path = "packages/dioxus-lib", version = "0.5.0" }
dioxus-core = { path = "packages/core", default-features = false, version = "0.5.0" }
dioxus-core-macro = { path = "packages/core-macro", version = "0.5.0" }
Expand Down Expand Up @@ -161,7 +161,7 @@ base64 = { version = "0.21.0", optional = true }
tracing.workspace = true

[dev-dependencies]
dioxus = { workspace = true, features = ["router"] }
dioxus = { workspace = true, features = ["router"], default-features = true }
dioxus-ssr = { workspace = true }
futures-util = "0.3.21"
separator = "0.4.1"
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/diff/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ impl VNode {
}

/// Get the most up to date template for this rsx block
#[allow(unused)]
pub(crate) fn template(&self, dom: &VirtualDom) -> Template {
// check for a overridden template
#[cfg(debug_assertions)]
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/virtual_dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
nodes::{Template, TemplateId},
runtime::{Runtime, RuntimeGuard},
scopes::ScopeId,
AttributeValue, ComponentFunction, Element, Event, Mutations, VNode,
AttributeValue, ComponentFunction, Element, Event, Mutations,
};
use futures_util::StreamExt;
use slab::Slab;
Expand Down Expand Up @@ -577,7 +577,7 @@ impl VirtualDom {
let mut dirty = Vec::new();
for (id, scope) in self.scopes.iter() {
// Recurse into the dynamic nodes of the existing mounted node to see if the template is alive in the tree
fn check_node_for_templates(node: &VNode, template: Template) -> bool {
fn check_node_for_templates(node: &crate::VNode, template: Template) -> bool {
let this_template_name = node.template.get().name.rsplit_once(':').unwrap().0;

if this_template_name == template.name.rsplit_once(':').unwrap().0 {
Expand Down
18 changes: 8 additions & 10 deletions packages/fullstack/src/html_storage/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,23 @@ use super::SerializeContext;
#[allow(unused)]
pub(crate) fn serde_to_writable<T: Serialize>(
value: &T,
write_to: &mut impl std::io::Write,
) -> Result<(), ciborium::ser::Error<std::io::Error>> {
write_to: &mut impl std::fmt::Write,
) -> Result<(), ciborium::ser::Error<std::fmt::Error>> {
let mut serialized = Vec::new();
ciborium::into_writer(value, &mut serialized)?;
write_to.write_all(STANDARD.encode(serialized).as_bytes())?;
ciborium::into_writer(value, &mut serialized).unwrap();
write_to.write_str(STANDARD.encode(serialized).as_str())?;
Ok(())
}

#[cfg(feature = "server")]
/// Encode data into a element. This is inteded to be used in the server to send data to the client.
pub(crate) fn encode_in_element(
data: &super::HTMLData,
write_to: &mut impl std::io::Write,
) -> Result<(), ciborium::ser::Error<std::io::Error>> {
write_to.write_all(
r#"<meta hidden="true" id="dioxus-storage-data" data-serialized=""#.as_bytes(),
)?;
write_to: &mut impl std::fmt::Write,
) -> Result<(), ciborium::ser::Error<std::fmt::Error>> {
write_to.write_str(r#"<meta hidden="true" id="dioxus-storage-data" data-serialized=""#)?;
serde_to_writable(&data, write_to)?;
Ok(write_to.write_all(r#"" />"#.as_bytes())?)
Ok(write_to.write_str(r#"" />"#)?)
}

impl super::HTMLData {
Expand Down
4 changes: 0 additions & 4 deletions packages/fullstack/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ pub mod prelude {
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
pub use crate::render::{FullstackHTMLTemplate, SSRState};

#[cfg(feature = "router")]
#[cfg_attr(docsrs, doc(cfg(feature = "router")))]
pub use crate::router::FullstackRouterConfig;

#[cfg(feature = "server")]
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
pub use crate::serve_config::{ServeConfig, ServeConfigBuilder};
Expand Down
86 changes: 22 additions & 64 deletions packages/fullstack/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,20 +162,11 @@ impl SsrRendererPool {
let join_handle = spawn_platform(move || async move {
let mut virtual_dom = virtual_dom_factory();

let mut pre_body = WriteBuffer { buffer: Vec::new() };
if let Err(err) = wrapper.render_before_body(&mut *pre_body) {
let mut pre_body = String::new();
if let Err(err) = wrapper.render_before_body(&mut pre_body) {
_ = into.start_send(Err(err));
return;
}
let pre_body = match String::from_utf8(pre_body.buffer) {
Ok(html) => html,
Err(err) => {
_ = into.start_send(Err(
dioxus_ssr::incremental::IncrementalRendererError::Other(Box::new(err)),
));
return;
}
};

let mut streaming_renderer = StreamingRenderer::new(pre_body, into);

Expand Down Expand Up @@ -247,44 +238,31 @@ impl SsrRendererPool {
tracing::info!("Suspense resolved");

// After suspense is done, we render one last time to get the final html that can be hydrated and then close the body
let mut post_streaming = WriteBuffer { buffer: Vec::new() };
let mut post_streaming = String::new();

// We need to include hydration ids in final the SSR render so that the client can hydrate the correct nodes
renderer.pre_render = true;
if let Err(err) = renderer.render_to(&mut post_streaming, &virtual_dom) {
throw_error!(dioxus_ssr::incremental::IncrementalRendererError::RenderError(err));
}

// Extract any data we serialized for hydration (from server futures)
let html_data = crate::html_storage::HTMLData::extract_from_virtual_dom(&virtual_dom);

if let Err(err) = wrapper.render_after_body(&mut *post_streaming, &html_data) {
if let Err(err) = wrapper.render_after_body(&mut post_streaming, &virtual_dom) {
throw_error!(err);
}

// If incremental rendering is enabled, add the new render to the cache without the streaming bits
if let Some(incremental) = &self.incremental_cache {
let mut cached_render = WriteBuffer { buffer: Vec::new() };
if let Err(err) = wrapper.render_before_body(&mut *cached_render) {
let mut cached_render = String::new();
if let Err(err) = wrapper.render_before_body(&mut cached_render) {
throw_error!(err);
}
cached_render
.buffer
.extend_from_slice(post_streaming.buffer.as_slice());
cached_render.push_str(&post_streaming);

if let Ok(mut incremental) = incremental.write() {
let _ = incremental.cache(route, cached_render.buffer);
let _ = incremental.cache(route, cached_render);
}
}

let post_streaming = match String::from_utf8(post_streaming.buffer) {
Ok(html) => html,
Err(err) => {
throw_error!(dioxus_ssr::incremental::IncrementalRendererError::Other(
Box::new(err),
));
}
};
streaming_renderer.finish_streaming(post_streaming);

myself.renderers.write().unwrap().push(renderer);
Expand Down Expand Up @@ -350,24 +328,29 @@ impl FullstackHTMLTemplate {
}

impl FullstackHTMLTemplate {
fn render_before_body<R: std::io::Write>(
/// Render any content before the body of the page.
pub fn render_before_body<R: std::fmt::Write>(
&self,
to: &mut R,
) -> Result<(), dioxus_ssr::incremental::IncrementalRendererError> {
let ServeConfig { index, .. } = &self.cfg;

to.write_all(index.pre_main.as_bytes())?;
to.write_str(&index.pre_main)?;

Ok(())
}

fn render_after_body<R: std::io::Write>(
/// Render all content after the body of the page.
pub fn render_after_body<R: std::fmt::Write>(
&self,
to: &mut R,
html_data: &crate::html_storage::HTMLData,
vdom: &VirtualDom,
) -> Result<(), dioxus_ssr::incremental::IncrementalRendererError> {
// Extract any data we serialized for hydration (from server futures)
let html_data = crate::html_storage::HTMLData::extract_from_virtual_dom(vdom);

// serialize the server state
crate::html_storage::serialize::encode_in_element(html_data, to).map_err(|err| {
crate::html_storage::serialize::encode_in_element(&html_data, to).map_err(|err| {
dioxus_ssr::incremental::IncrementalRendererError::Other(Box::new(err))
})?;

Expand All @@ -376,14 +359,14 @@ impl FullstackHTMLTemplate {
// In debug mode, we need to add a script to the page that will reload the page if the websocket disconnects to make full recompile hot reloads work
let disconnect_js = dioxus_hot_reload::RECONNECT_SCRIPT;

to.write_all(r#"<script>"#.as_bytes())?;
to.write_all(disconnect_js.as_bytes())?;
to.write_all(r#"</script>"#.as_bytes())?;
to.write_str(r#"<script>"#)?;
to.write_str(disconnect_js)?;
to.write_str(r#"</script>"#)?;
}

let ServeConfig { index, .. } = &self.cfg;

to.write_all(index.post_main.as_bytes())?;
to.write_str(&index.post_main)?;

Ok(())
}
Expand All @@ -394,28 +377,3 @@ fn pre_renderer() -> Renderer {
renderer.pre_render = true;
renderer
}

struct WriteBuffer {
buffer: Vec<u8>,
}

impl std::fmt::Write for WriteBuffer {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
self.buffer.extend_from_slice(s.as_bytes());
Ok(())
}
}

impl std::ops::Deref for WriteBuffer {
type Target = Vec<u8>;

fn deref(&self) -> &Self::Target {
&self.buffer
}
}

impl std::ops::DerefMut for WriteBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
1 change: 1 addition & 0 deletions packages/fullstack/src/server_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ mod server_fn_impl {
}

/// Create a server context from a shared parts
#[allow(unused)]
pub(crate) fn from_shared_parts(parts: Arc<RwLock<http::request::Parts>>) -> Self {
Self {
parts,
Expand Down
4 changes: 2 additions & 2 deletions packages/liveview/src/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ pub fn launch(
contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
platform_config: Config,
) {
#[cfg(feature = "multi-threaded")]
#[cfg(feature = "multi-thread")]
let mut builder = tokio::runtime::Builder::new_multi_thread();
#[cfg(not(feature = "multi-threaded"))]
#[cfg(not(feature = "multi-thread"))]
let mut builder = tokio::runtime::Builder::new_current_thread();

builder.enable_all().build().unwrap().block_on(async move {
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-tests/fullstack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dioxus = { workspace = true, features = ["fullstack"] }
dioxus = { workspace = true, features = ["fullstack"], default-features = true }
serde = "1.0.159"

[features]
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-tests/liveview/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
publish = false

[dependencies]
dioxus = { workspace = true }
dioxus = { workspace = true, default-features = true }
dioxus-liveview = { workspace = true, features = ["axum"] }
tokio = { version = "1.19.2", features = ["full"] }
axum = { workspace = true, features = ["ws"] }
2 changes: 1 addition & 1 deletion packages/playwright-tests/web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
publish = false

[dependencies]
dioxus = { workspace = true, features = ["web"]}
dioxus = { workspace = true, features = ["web"], default-features = true }
serde_json = "1.0.96"
tracing.workspace = true
tracing-wasm = "0.2.1"
8 changes: 1 addition & 7 deletions packages/router/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ wasm-bindgen-test = "0.3.33"

[features]
default = []
ssr = ["dioxus-ssr/incremental", "tokio", "dioxus-fullstack?/server", "http"]
ssr = []
liveview = ["dioxus-liveview", "tokio", "dep:serde", "serde_json"]
wasm_test = []
web = ["gloo", "web-sys", "wasm-bindgen", "gloo-utils", "js-sys", "dioxus-router-macro/web"]
Expand All @@ -59,12 +59,6 @@ serde = { version = "1", features = ["derive"] }

[package.metadata.docs.rs]
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]

[[bench]]
name = "incremental"
required-features = ["ssr"]
harness = false

# Most of the examples live in the workspace. We include some here so that docs.rs can scrape our examples for better inline docs
[[example]]
name = "crm"
Expand Down
69 changes: 0 additions & 69 deletions packages/router/src/incremental.rs

This file was deleted.

Loading

0 comments on commit ab1d474

Please sign in to comment.