1use std::ops::{Deref, DerefMut};
2
3use dioxus_lib::prelude::*;
4
5mod macros;
6pub mod re_exports;
8
9#[allow(async_fn_in_trait)]
10pub trait DataKey {
11 type Value: Clone + Send + Sync + 'static;
12 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
40pub 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}