Directly use and return read / write signal given by default_value

This commit is contained in:
Joshua McQuistan 2023-11-04 13:30:36 +00:00
parent a28bbb33e4
commit 389b6e6811

View file

@ -189,12 +189,13 @@ where
default_value, default_value,
filter, filter,
} = options; } = options;
let (default, _) = default_value.into_signal();
let (data, set_data) = default_value.into_signal();
let default = data.get_untracked();
cfg_if! { if #[cfg(feature = "ssr")] { cfg_if! { if #[cfg(feature = "ssr")] {
let (data, set_data) = create_signal(default.get_untracked());
let remove = move || { let remove = move || {
set_data.set(default.get_untracked()); set_data.set(default.clone());
}; };
(data.into(), set_data, remove) (data.into(), set_data, remove)
} else { } else {
@ -230,24 +231,14 @@ where
} }
}; };
// Fires when storage needs to be updated // Fetches direct from browser storage and fills set_data if changed (memo)
let notify = create_trigger(); let fetch_from_storage = {
// Keeps track of how many times we've been notified. Does not increment for calls to set_data
let notify_id = create_memo::<usize>(move |prev| {
notify.track();
prev.map(|prev| prev + 1).unwrap_or_default()
});
// Fetch from storage and falls back to the default (possibly a signal) if deleted
let fetcher = {
let storage = storage.to_owned(); let storage = storage.to_owned();
let codec = codec.to_owned(); let codec = codec.to_owned();
let key = key.as_ref().to_owned(); let key = key.as_ref().to_owned();
let on_error = on_error.to_owned(); let on_error = on_error.to_owned();
create_memo(move |_| { move || {
notify.track(); let fetched = storage
storage
.to_owned() .to_owned()
.and_then(|storage| { .and_then(|storage| {
// Get directly from storage // Get directly from storage
@ -265,17 +256,41 @@ where
handle_error(&on_error, result) handle_error(&on_error, result)
}) })
.transpose() .transpose()
.unwrap_or_default() // Drop handled Err(()) .unwrap_or_default(); // Drop handled Err(())
// Fallback to default
.unwrap_or_else(move || default.get()) match fetched {
}) Some(value) => {
// Replace data if changed
if value != data.get_untracked() {
set_data.set(value)
}
}
// Revert to default
None => set_data.set(default.clone()),
};
}
}; };
// Create mutable data signal from our fetcher // Fetch initial value
let (data, set_data) = MaybeRwSignal::<T>::from(fetcher).into_signal(); fetch_from_storage();
let data = create_memo(move |_| data.get());
// Set storage value on data change // Fires when storage needs to be fetched
let notify = create_trigger();
// Refetch from storage. Keeps track of how many times we've been notified. Does not increment for calls to set_data
let notify_id = create_memo::<usize>(move |prev| {
notify.track();
match prev {
None => 1, // Avoid async fetch of initial value
Some(prev) => {
fetch_from_storage();
prev + 1
}
}
});
// Set item on internal (non-event) page changes to the data signal
{ {
let storage = storage.to_owned(); let storage = storage.to_owned();
let codec = codec.to_owned(); let codec = codec.to_owned();
@ -310,7 +325,7 @@ where
}, },
WatchOptions::default().filter(filter), WatchOptions::default().filter(filter),
); );
}; }
if listen_to_storage_changes { if listen_to_storage_changes {
let check_key = key.as_ref().to_owned(); let check_key = key.as_ref().to_owned();