Files
dioxus/packages/fullstack-core/src/server_cached.rs
T
Jonathan Kelley f2b1c6d97f codify "platform" into resolution logic, server-fn/fullstack overhaul (#4596)
overhaul dioxus fullstack using a new implementation of server_fn

This PR is a complete rewrite of dioxus fullstack designed to improve compatibility with axum and to fix a number of compilation errors based on feature flag unification plumbing through macros.
2025-10-03 18:26:19 -07:00

102 lines
3.0 KiB
Rust

use crate::transport::SerializeContextEntry;
use dioxus_core::use_hook;
use serde::{de::DeserializeOwned, Serialize};
/// This allows you to send data from the server to the client *during hydration*.
/// - When compiled as server, the closure is ran and the resulting data is serialized on the server and sent to the client.
/// - When compiled as web client, the data is deserialized from the server if already available, otherwise runs on the client. Data is usually only available if this hook exists in a component during hydration.
/// - When otherwise compiled, the closure is run directly with no serialization.
///
/// The order this function is run on the client needs to be the same order initially run on the server.
///
/// If Dioxus fullstack cannot find the data on the client, it will run the closure again to get the data.
///
/// # Example
/// ```rust
/// use dioxus::prelude::*;
///
/// fn app() -> Element {
/// let state1 = use_server_cached(|| {
/// 1234
/// });
///
/// unimplemented!()
/// }
/// ```
#[track_caller]
pub fn use_server_cached<O: 'static + Clone + Serialize + DeserializeOwned>(
server_fn: impl Fn() -> O,
) -> O {
let location = std::panic::Location::caller();
use_hook(|| server_cached(server_fn, location))
}
pub(crate) fn server_cached<O: 'static + Clone + Serialize + DeserializeOwned>(
value: impl FnOnce() -> O,
#[allow(unused)] location: &'static std::panic::Location<'static>,
) -> O {
let serialize = crate::serialize_context();
#[allow(unused)]
let entry: SerializeContextEntry<O> = serialize.create_entry();
#[cfg(feature = "server")]
{
let data = value();
entry.insert(&data, location);
data
}
#[cfg(all(not(feature = "server"), feature = "web"))]
{
match entry.get() {
Ok(value) => value,
Err(_) => value(),
}
}
#[cfg(not(any(feature = "server", feature = "web")))]
{
value()
}
}
// pub fn use_server_cached<O, M>(server_fn: impl Fn() -> O) -> O
// where
// O: Transportable<M> + Clone,
// M: 'static,
// {
// let location = std::panic::Location::caller();
// use_hook(|| server_cached(server_fn, location))
// }
// pub(crate) fn server_cached<O, M>(
// value: impl FnOnce() -> O,
// #[allow(unused)] location: &'static std::panic::Location<'static>,
// ) -> O
// where
// O: Transportable<M> + Clone,
// M: 'static,
// {
// let serialize = crate::transport::serialize_context();
// #[allow(unused)]
// let entry: SerializeContextEntry<O> = serialize.create_entry();
// #[cfg(feature = "server")]
// {
// let data = value();
// entry.insert(&data, location);
// data
// }
// #[cfg(all(not(feature = "server"), feature = "web"))]
// {
// match entry.get() {
// Ok(value) => value,
// Err(_) => value(),
// }
// }
// #[cfg(not(any(feature = "server", feature = "web")))]
// {
// value()
// }
// }