dioxus_keys/
lib.rs

1use std::ops::{Deref, DerefMut};
2
3use dioxus_lib::prelude::*;
4
5mod macros;
6/// re exports for the macros to use
7pub mod re_exports;
8
9#[allow(async_fn_in_trait)]
10pub trait DataKey {
11    type Value: Clone + Send + Sync + 'static;
12    /// CAUTION: since this runs in an use_resource BE CAUTIOUS OF CYCLES WHEN USING THE GLOBAL DATA SIGNAL.
13    async fn init();
14    async fn on_change();
15    async fn on_drop();
16
17    #[track_caller]
18    fn read() -> ReadableRef<'static, Signal<Self::Value, SyncStorage>> {
19        Self::try_read().unwrap()
20    }
21
22    #[track_caller]
23    fn peek() -> ReadableRef<'static, Signal<Self::Value, SyncStorage>> {
24        Self::try_read().unwrap()
25    }
26
27    fn try_read() -> Option<ReadableRef<'static, Signal<Self::Value, SyncStorage>>>;
28    fn try_peek() -> Option<ReadableRef<'static, Signal<Self::Value, SyncStorage>>>;
29}
30
31pub trait WritableDataKey: DataKey {
32    #[track_caller]
33    fn write() -> WritableRef<'static, Signal<Self::Value, SyncStorage>> {
34        Self::try_write().unwrap()
35    }
36
37    fn try_write() -> Option<WritableRef<'static, Signal<Self::Value, SyncStorage>>>;
38}
39
40/// make sure the resource returned by this is complete before using any keys.
41pub fn use_init_key<K: DataKey<Value = V>, V: Clone + Send + Sync + 'static>(
42    _key: K,
43) -> Resource<()> {
44    use_effect(move || {
45        let val = K::try_read();
46        if val.is_some() {
47            spawn(async { K::on_change().await });
48        }
49    });
50
51    use_drop(|| {
52        spawn(async { K::on_drop().await });
53    });
54
55    use_resource(|| async { K::init().await })
56}