work on fixing ssr

This commit is contained in:
Evan Almloff 2024-01-10 09:56:03 -06:00
parent d8e79b656b
commit 5b2b0c43bd
5 changed files with 21 additions and 37 deletions

View file

@ -6,7 +6,7 @@ use crate::renderer::{str_truthy, BOOL_ATTRS};
#[derive(Debug)]
pub struct StringCache {
pub segments: Vec<Segment>,
pub template: Template<'static>,
pub template: Template,
}
#[derive(Default)]

View file

@ -1,12 +1,12 @@
use async_trait::async_trait;
use dioxus_core::ScopeState;
use dioxus_core::ScopeId;
use dioxus_html::prelude::{EvalError, EvalProvider, Evaluator};
use std::rc::Rc;
/// Provides the SSREvalProvider through [`cx.provide_context`].
pub fn init_eval(cx: &ScopeState) {
pub fn init_eval() {
let provider: Rc<dyn EvalProvider> = Rc::new(SSREvalProvider {});
cx.provide_context(provider);
ScopeId::ROOT.provide_context(provider);
}
/// Reprents the ssr-target's provider of evaluators.

View file

@ -3,7 +3,7 @@
#![allow(non_snake_case)]
use crate::fs_cache::ValidCachedPath;
use dioxus_core::{Element, Scope, VirtualDom};
use dioxus_core::{Element, VirtualDom};
use rustc_hash::FxHasher;
use std::{
future::Future,
@ -69,10 +69,10 @@ impl IncrementalRenderer {
self.invalidate_after.is_some()
}
async fn render_and_cache<'a, P: 'static, R: WrapBody + Send + Sync>(
async fn render_and_cache<'a, P: Clone + 'static, R: WrapBody + Send + Sync>(
&'a mut self,
route: String,
comp: fn(Scope<P>) -> Element,
comp: fn(P) -> Element,
props: P,
output: &'a mut (impl AsyncWrite + Unpin + Send),
rebuild_with: impl FnOnce(&mut VirtualDom) -> Pin<Box<dyn Future<Output = ()> + '_>>,
@ -81,7 +81,7 @@ impl IncrementalRenderer {
let mut html_buffer = WriteBuffer { buffer: Vec::new() };
{
let mut vdom = VirtualDom::new_with_props(comp, props);
crate::eval::init_eval(vdom.base_scope());
vdom.in_runtime(crate::eval::init_eval);
rebuild_with(&mut vdom).await;
renderer.render_before_body(&mut *html_buffer)?;
@ -168,10 +168,10 @@ impl IncrementalRenderer {
}
/// Render a route or get it from cache.
pub async fn render<P: 'static, R: WrapBody + Send + Sync>(
pub async fn render<P: Clone + 'static, R: WrapBody + Send + Sync>(
&mut self,
route: String,
component: fn(Scope<P>) -> Element,
component: fn(P) -> Element,
props: P,
output: &mut (impl AsyncWrite + Unpin + std::marker::Send),
rebuild_with: impl FnOnce(&mut VirtualDom) -> Pin<Box<dyn Future<Output = ()> + '_>>,

View file

@ -14,37 +14,21 @@ pub mod eval;
pub mod renderer;
pub mod template;
use dioxus_core::{Element, LazyNodes, Scope, VirtualDom};
use std::cell::Cell;
use dioxus_core::{Element, VirtualDom};
pub use crate::renderer::Renderer;
/// A convenience function to render an `rsx!` call to a string
/// A convenience function to render an `render!` call to a string
///
/// For advanced rendering, create a new `SsrRender`.
pub fn render_lazy(f: LazyNodes<'_, '_>) -> String {
// We need to somehow get the lazy call into the virtualdom even with the lifetime
// Since the lazy lifetime is valid for this function, we can just transmute it to static temporarily
// This is okay since we're returning an owned value
struct RootProps<'a, 'b> {
caller: Cell<Option<LazyNodes<'a, 'b>>>,
pub fn render_element(element: Element) -> String {
fn lazy_app(props: Element) -> Element {
props
}
fn lazy_app<'a>(cx: Scope<'a, RootProps<'static, 'static>>) -> Element<'a> {
let lazy = cx.props.caller.take().unwrap();
let lazy: LazyNodes = unsafe { std::mem::transmute(lazy) };
Some(lazy.call(cx))
}
let props: RootProps = unsafe {
std::mem::transmute(RootProps {
caller: Cell::new(Some(f)),
})
};
let mut dom = VirtualDom::new_with_props(lazy_app, props);
crate::eval::init_eval(dom.base_scope());
_ = dom.rebuild();
let mut dom = VirtualDom::new_with_props(lazy_app, element);
dom.in_runtime(crate::eval::init_eval);
_ = dom.rebuild(&mut NoOpMutations);
Renderer::new().render(&dom)
}

View file

@ -2,7 +2,7 @@ use super::cache::Segment;
use crate::cache::StringCache;
use dioxus_core::Attribute;
use dioxus_core::{prelude::*, AttributeValue, DynamicNode, RenderReturn};
use dioxus_core::{prelude::*, AttributeValue, DynamicNode};
use std::collections::HashMap;
use std::fmt::Write;
use std::sync::Arc;
@ -141,7 +141,7 @@ impl Renderer {
write!(
buf,
"{}",
askama_escape::escape(text.value, askama_escape::Html)
askama_escape::escape(&text.value, askama_escape::Html)
)?;
if self.pre_render {
@ -149,7 +149,7 @@ impl Renderer {
}
}
DynamicNode::Fragment(nodes) => {
for child in *nodes {
for child in nodes {
self.render_template(buf, dom, child)?;
}
}