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// }