feat(fullstack): support wasm target
This commit is contained in:
1 parent
a454f2c7ac
commit
1f0e03ca19
9 files changed
+190
-128
No files matched your search
@@ -7,13 +7,33 @@ use dioxus_ssr::{
|
||||
Renderer,
|
||||
};
|
||||
use serde::Serialize;
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use tokio::task::spawn_blocking;
|
||||
use tokio::task::{spawn_blocking, JoinHandle};
|
||||
|
||||
use crate::prelude::*;
|
||||
use dioxus_lib::prelude::*;
|
||||
|
||||
fn spawn_platform<Fut>(f: impl FnOnce() -> Fut + Send + 'static) -> JoinHandle<Fut::Output>
|
||||
where
|
||||
Fut: Future + 'static,
|
||||
Fut::Output: Send + 'static,
|
||||
{
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
spawn_blocking(move || {
|
||||
tokio::runtime::Runtime::new()
|
||||
.expect("couldn't spawn runtime")
|
||||
.block_on(f())
|
||||
})
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
tokio::task::spawn_local(f())
|
||||
}
|
||||
}
|
||||
|
||||
enum SsrRendererPool {
|
||||
Renderer(RwLock<Vec<Renderer>>),
|
||||
Incremental(RwLock<Vec<dioxus_ssr::incremental::IncrementalRenderer>>),
|
||||
@@ -39,51 +59,41 @@ impl SsrRendererPool {
|
||||
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
|
||||
spawn_blocking(move || {
|
||||
tokio::runtime::Runtime::new()
|
||||
.expect("couldn't spawn runtime")
|
||||
.block_on(async move {
|
||||
let mut vdom = virtual_dom_factory();
|
||||
let mut to = WriteBuffer { buffer: Vec::new() };
|
||||
// before polling the future, we need to set the context
|
||||
let prev_context =
|
||||
SERVER_CONTEXT.with(|ctx| ctx.replace(server_context));
|
||||
// poll the future, which may call server_context()
|
||||
tracing::info!("Rebuilding vdom");
|
||||
let _ = vdom.rebuild(&mut NoOpMutations);
|
||||
vdom.wait_for_suspense().await;
|
||||
tracing::info!("Suspense resolved");
|
||||
// after polling the future, we need to restore the context
|
||||
SERVER_CONTEXT.with(|ctx| ctx.replace(prev_context));
|
||||
spawn_platform(move || async move {
|
||||
let mut vdom = virtual_dom_factory();
|
||||
let mut to = WriteBuffer { buffer: Vec::new() };
|
||||
// before polling the future, we need to set the context
|
||||
let prev_context = SERVER_CONTEXT.with(|ctx| ctx.replace(server_context));
|
||||
// poll the future, which may call server_context()
|
||||
tracing::info!("Rebuilding vdom");
|
||||
let _ = vdom.rebuild(&mut NoOpMutations);
|
||||
vdom.wait_for_suspense().await;
|
||||
tracing::info!("Suspense resolved");
|
||||
// after polling the future, we need to restore the context
|
||||
SERVER_CONTEXT.with(|ctx| ctx.replace(prev_context));
|
||||
|
||||
if let Err(err) = wrapper.render_before_body(&mut *to) {
|
||||
let _ = tx.send(Err(err));
|
||||
return;
|
||||
}
|
||||
if let Err(err) = renderer.render_to(&mut to, &vdom) {
|
||||
let _ = tx.send(Err(
|
||||
dioxus_ssr::incremental::IncrementalRendererError::RenderError(
|
||||
err,
|
||||
),
|
||||
));
|
||||
return;
|
||||
}
|
||||
if let Err(err) = wrapper.render_after_body(&mut *to) {
|
||||
let _ = tx.send(Err(err));
|
||||
return;
|
||||
}
|
||||
match String::from_utf8(to.buffer) {
|
||||
Ok(html) => {
|
||||
let _ =
|
||||
tx.send(Ok((renderer, RenderFreshness::now(None), html)));
|
||||
}
|
||||
Err(err) => {
|
||||
dioxus_ssr::incremental::IncrementalRendererError::Other(
|
||||
Box::new(err),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
if let Err(err) = wrapper.render_before_body(&mut *to) {
|
||||
let _ = tx.send(Err(err));
|
||||
return;
|
||||
}
|
||||
if let Err(err) = renderer.render_to(&mut to, &vdom) {
|
||||
let _ = tx.send(Err(
|
||||
dioxus_ssr::incremental::IncrementalRendererError::RenderError(err),
|
||||
));
|
||||
return;
|
||||
}
|
||||
if let Err(err) = wrapper.render_after_body(&mut *to) {
|
||||
let _ = tx.send(Err(err));
|
||||
return;
|
||||
}
|
||||
match String::from_utf8(to.buffer) {
|
||||
Ok(html) => {
|
||||
let _ = tx.send(Ok((renderer, RenderFreshness::now(None), html)));
|
||||
}
|
||||
Err(err) => {
|
||||
dioxus_ssr::incremental::IncrementalRendererError::Other(Box::new(err));
|
||||
}
|
||||
}
|
||||
});
|
||||
let (renderer, freshness, html) = rx.await.unwrap()?;
|
||||
pool.write().unwrap().push(renderer);
|
||||
@@ -98,53 +108,49 @@ impl SsrRendererPool {
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
|
||||
let server_context = server_context.clone();
|
||||
spawn_blocking(move || {
|
||||
tokio::runtime::Runtime::new()
|
||||
.expect("couldn't spawn runtime")
|
||||
.block_on(async move {
|
||||
let mut to = WriteBuffer { buffer: Vec::new() };
|
||||
match renderer
|
||||
.render(
|
||||
route,
|
||||
virtual_dom_factory,
|
||||
&mut *to,
|
||||
|vdom| {
|
||||
Box::pin(async move {
|
||||
// before polling the future, we need to set the context
|
||||
let prev_context = SERVER_CONTEXT
|
||||
.with(|ctx| ctx.replace(Box::new(server_context)));
|
||||
// poll the future, which may call server_context()
|
||||
tracing::info!("Rebuilding vdom");
|
||||
let _ = vdom.rebuild(&mut NoOpMutations);
|
||||
vdom.wait_for_suspense().await;
|
||||
tracing::info!("Suspense resolved");
|
||||
// after polling the future, we need to restore the context
|
||||
SERVER_CONTEXT.with(|ctx| ctx.replace(prev_context));
|
||||
})
|
||||
},
|
||||
&wrapper,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(freshness) => {
|
||||
match String::from_utf8(to.buffer).map_err(|err| {
|
||||
dioxus_ssr::incremental::IncrementalRendererError::Other(
|
||||
Box::new(err),
|
||||
)
|
||||
}) {
|
||||
Ok(html) => {
|
||||
let _ = tx.send(Ok((freshness, html)));
|
||||
}
|
||||
Err(err) => {
|
||||
let _ = tx.send(Err(err));
|
||||
}
|
||||
}
|
||||
spawn_platform(move || async move {
|
||||
let mut to = WriteBuffer { buffer: Vec::new() };
|
||||
match renderer
|
||||
.render(
|
||||
route,
|
||||
virtual_dom_factory,
|
||||
&mut *to,
|
||||
|vdom| {
|
||||
Box::pin(async move {
|
||||
// before polling the future, we need to set the context
|
||||
let prev_context = SERVER_CONTEXT
|
||||
.with(|ctx| ctx.replace(Box::new(server_context)));
|
||||
// poll the future, which may call server_context()
|
||||
tracing::info!("Rebuilding vdom");
|
||||
let _ = vdom.rebuild(&mut NoOpMutations);
|
||||
vdom.wait_for_suspense().await;
|
||||
tracing::info!("Suspense resolved");
|
||||
// after polling the future, we need to restore the context
|
||||
SERVER_CONTEXT.with(|ctx| ctx.replace(prev_context));
|
||||
})
|
||||
},
|
||||
&wrapper,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(freshness) => {
|
||||
match String::from_utf8(to.buffer).map_err(|err| {
|
||||
dioxus_ssr::incremental::IncrementalRendererError::Other(Box::new(
|
||||
err,
|
||||
))
|
||||
}) {
|
||||
Ok(html) => {
|
||||
let _ = tx.send(Ok((freshness, html)));
|
||||
}
|
||||
Err(err) => {
|
||||
let _ = tx.send(Err(err));
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Err(err) => {
|
||||
let _ = tx.send(Err(err));
|
||||
}
|
||||
}
|
||||
});
|
||||
let (freshness, html) = rx.await.unwrap()?;
|
||||
|
||||
|
||||
Reference in new issue
Block a user