vertigo 0.11.4

Reactive Real-DOM library with SSR for Rust
Documentation
use crate::{
    Computed, DropResource,
    computed::{Value, ValueSynchronize, context::Context},
    driver_module::api::api_timers,
    fetch::api_response::ApiResponse,
};

pub struct CacheValue<T: PartialEq + 'static> {
    value_write: Value<ApiResponse<T>>,
    value_read: Computed<ApiResponse<T>>,
}

impl<T: PartialEq> Clone for CacheValue<T> {
    fn clone(&self) -> Self {
        CacheValue {
            value_write: self.value_write.clone(),
            value_read: self.value_read.clone(),
        }
    }
}

impl<T: PartialEq + 'static> CacheValue<T> {
    pub fn new(init_value: ApiResponse<T>, bearer_auth: Computed<Option<String>>) -> CacheValue<T> {
        let value_write = Value::new(init_value);

        let value_read: Computed<ApiResponse<T>> = {
            let value_write = value_write.clone();
            let bearer_auth = bearer_auth;

            value_write.to_computed().when_connect({
                let bearer_auth = bearer_auth.clone();

                move || {
                    let value_write = value_write.clone();

                    let revalidate_trigger = bearer_auth.clone();

                    let drop = revalidate_trigger.subscribe(move |_new_token| {
                        let value_write = value_write.clone();

                        api_timers().set_timeout_and_detach(0, move || {
                            value_write.set(ApiResponse::Uninitialized);
                        });
                    });

                    DropResource::new(move || {
                        drop.off();
                    })
                }
            })
        };

        CacheValue {
            value_write,
            value_read,
        }
    }

    pub fn get(&self, context: &Context) -> ApiResponse<T> {
        self.value_read.get(context)
    }

    pub fn set(&self, value: ApiResponse<T>) {
        self.value_write.set(value);
    }

    pub fn synchronize<R: ValueSynchronize<std::rc::Rc<T>> + Clone + 'static>(
        &self,
    ) -> (R, DropResource)
    where
        T: Default + Clone,
    {
        use crate::{Resource, transaction};
        use std::rc::Rc;
        use vertigo_macro::bind;

        fn normalize<T: Default>(val: ApiResponse<T>) -> Rc<T> {
            match val {
                ApiResponse::Uninitialized => Rc::new(T::default()),
                ApiResponse::Data { value, expiry: _ } => match value {
                    Resource::Ready(data) => data,
                    Resource::Loading => Rc::new(T::default()),
                    Resource::Error(_) => Rc::new(T::default()),
                },
            }
        }

        let init_val = transaction(|ctx| normalize(self.value_write.get(ctx)));
        let target = R::new(init_val);

        let drop = self.value_write.add_event(bind!(target, |val| {
            target.set(normalize(val));
        }));

        (target, drop)
    }
}