dioxus_fullstack_core/server_cached.rs
1use crate::transport::SerializeContextEntry;
2use dioxus_core::use_hook;
3use serde::{de::DeserializeOwned, Serialize};
4
5/// This allows you to send data from the server to the client *during hydration*.
6/// - When compiled as server, the closure is ran and the resulting data is serialized on the server and sent to the client.
7/// - 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.
8/// - When otherwise compiled, the closure is run directly with no serialization.
9///
10/// The order this function is run on the client needs to be the same order initially run on the server.
11///
12/// If Dioxus fullstack cannot find the data on the client, it will run the closure again to get the data.
13///
14/// # Example
15/// ```rust
16/// use dioxus::prelude::*;
17///
18/// fn app() -> Element {
19/// let state1 = use_server_cached(|| {
20/// 1234
21/// });
22///
23/// unimplemented!()
24/// }
25/// ```
26#[track_caller]
27pub fn use_server_cached<O: 'static + Clone + Serialize + DeserializeOwned>(
28 server_fn: impl Fn() -> O,
29) -> O {
30 let location = std::panic::Location::caller();
31 use_hook(|| server_cached(server_fn, location))
32}
33
34pub(crate) fn server_cached<O: 'static + Clone + Serialize + DeserializeOwned>(
35 value: impl FnOnce() -> O,
36 #[allow(unused)] location: &'static std::panic::Location<'static>,
37) -> O {
38 let serialize = crate::serialize_context();
39 #[allow(unused)]
40 let entry: SerializeContextEntry<O> = serialize.create_entry();
41 #[cfg(feature = "server")]
42 {
43 let data = value();
44 entry.insert(&data, location);
45 data
46 }
47 #[cfg(all(not(feature = "server"), feature = "web"))]
48 {
49 match entry.get() {
50 Ok(value) => value,
51 Err(_) => value(),
52 }
53 }
54 #[cfg(not(any(feature = "server", feature = "web")))]
55 {
56 value()
57 }
58}
59
60// pub fn use_server_cached<O, M>(server_fn: impl Fn() -> O) -> O
61// where
62// O: Transportable<M> + Clone,
63// M: 'static,
64// {
65// let location = std::panic::Location::caller();
66// use_hook(|| server_cached(server_fn, location))
67// }
68
69// pub(crate) fn server_cached<O, M>(
70// value: impl FnOnce() -> O,
71// #[allow(unused)] location: &'static std::panic::Location<'static>,
72// ) -> O
73// where
74// O: Transportable<M> + Clone,
75// M: 'static,
76// {
77// let serialize = crate::transport::serialize_context();
78
79// #[allow(unused)]
80// let entry: SerializeContextEntry<O> = serialize.create_entry();
81
82// #[cfg(feature = "server")]
83// {
84// let data = value();
85// entry.insert(&data, location);
86// data
87// }
88
89// #[cfg(all(not(feature = "server"), feature = "web"))]
90// {
91// match entry.get() {
92// Ok(value) => value,
93// Err(_) => value(),
94// }
95// }
96
97// #[cfg(not(any(feature = "server", feature = "web")))]
98// {
99// value()
100// }
101// }