123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- //! Exentsions to the incremental renderer to support pre-caching static routes.
- use core::pin::Pin;
- use std::future::Future;
- use std::str::FromStr;
- use dioxus::prelude::*;
- use dioxus_ssr::incremental::{
- IncrementalRenderer, IncrementalRendererError, RenderFreshness, WrapBody,
- };
- use crate::prelude::*;
- /// Pre-cache all static routes.
- pub async fn pre_cache_static_routes<Rt, R: WrapBody + Send + Sync>(
- renderer: &mut IncrementalRenderer,
- wrapper: &R,
- ) -> Result<(), IncrementalRendererError>
- where
- Rt: Routable,
- <Rt as FromStr>::Err: std::fmt::Display,
- {
- for route in Rt::SITE_MAP
- .iter()
- .flat_map(|seg| seg.flatten().into_iter())
- {
- // check if this is a static segment
- let mut is_static = true;
- let mut full_path = String::new();
- for segment in &route {
- match segment {
- SegmentType::Child => {}
- SegmentType::Static(s) => {
- full_path += "/";
- full_path += s;
- }
- _ => {
- // skip routes with any dynamic segments
- is_static = false;
- break;
- }
- }
- }
- if is_static {
- match Rt::from_str(&full_path) {
- Ok(route) => {
- render_route(
- renderer,
- route,
- &mut tokio::io::sink(),
- |vdom| {
- Box::pin(async move {
- let _ = vdom.wait_for_suspense().await;
- })
- },
- wrapper,
- )
- .await?;
- }
- Err(e) => {
- log::info!("@ route: {}", full_path);
- log::error!("Error pre-caching static route: {}", e);
- }
- }
- }
- }
- Ok(())
- }
- /// Render a route to a writer.
- pub async fn render_route<
- R: WrapBody + Send + Sync,
- Rt,
- W,
- F: FnOnce(&mut VirtualDom) -> Pin<Box<dyn Future<Output = ()> + '_>>,
- >(
- renderer: &mut IncrementalRenderer,
- route: Rt,
- writer: &mut W,
- modify_vdom: F,
- wrapper: &R,
- ) -> Result<RenderFreshness, IncrementalRendererError>
- where
- Rt: Routable,
- <Rt as FromStr>::Err: std::fmt::Display,
- W: tokio::io::AsyncWrite + Unpin + Send,
- {
- #[inline_props]
- fn RenderPath<R>(cx: Scope, path: R) -> Element
- where
- R: Routable,
- <R as FromStr>::Err: std::fmt::Display,
- {
- let path = path.clone();
- render! {
- GenericRouter::<R> {
- config: || RouterConfig::default().history(MemoryHistory::with_initial_path(path))
- }
- }
- }
- renderer
- .render(
- route.to_string(),
- RenderPath,
- RenderPathProps { path: route },
- writer,
- modify_vdom,
- wrapper,
- )
- .await
- }
|