mirror of
https://github.com/adoyle0/leptos-use.git
synced 2025-01-23 09:09:21 -05:00
Added more Send + Sync
bounds and SendWrapper
s
This commit is contained in:
parent
3433fc6608
commit
9866ac6231
14 changed files with 202 additions and 131 deletions
|
@ -4,8 +4,10 @@ use cfg_if::cfg_if;
|
|||
use leptos::html::{ElementType, HtmlElement};
|
||||
use leptos::prelude::wrappers::read::Signal;
|
||||
use leptos::prelude::*;
|
||||
use send_wrapper::SendWrapper;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
/// Used as an argument type to make it easily possible to pass either
|
||||
/// * a `web_sys` element that implements `E` (for example `EventTarget` or `Element`),
|
||||
|
@ -58,9 +60,9 @@ impl<T, E> With for ElementsMaybeSignal<T, E>
|
|||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
type Value = Vec<Option<T>>;
|
||||
type Value = Vec<Option<SendWrapper<T>>>;
|
||||
|
||||
fn with<O>(&self, f: impl FnOnce(&Vec<Option<T>>) -> O) -> O {
|
||||
fn with<O>(&self, f: impl FnOnce(&Vec<Option<SendWrapper<T>>>) -> O) -> O {
|
||||
match self {
|
||||
Self::Static(v) => f(v),
|
||||
Self::Dynamic(s) => s.with(f),
|
||||
|
@ -68,7 +70,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn try_with<O>(&self, f: impl FnOnce(&Vec<Option<T>>) -> O) -> Option<O> {
|
||||
fn try_with<O>(&self, f: impl FnOnce(&Vec<Option<SendWrapper<T>>>) -> O) -> Option<O> {
|
||||
match self {
|
||||
Self::Static(v) => Some(f(v)),
|
||||
Self::Dynamic(s) => s.try_with(f),
|
||||
|
@ -81,9 +83,9 @@ impl<T, E> WithUntracked for ElementsMaybeSignal<T, E>
|
|||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
type Value = Vec<Option<T>>;
|
||||
type Value = Vec<Option<SendWrapper<T>>>;
|
||||
|
||||
fn with_untracked<O>(&self, f: impl FnOnce(&Vec<Option<T>>) -> O) -> O {
|
||||
fn with_untracked<O>(&self, f: impl FnOnce(&Vec<Option<SendWrapper<T>>>) -> O) -> O {
|
||||
match self {
|
||||
Self::Static(t) => f(t),
|
||||
Self::Dynamic(s) => s.with_untracked(f),
|
||||
|
@ -91,7 +93,10 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn try_with_untracked<O>(&self, f: impl FnOnce(&Vec<Option<T>>) -> O) -> Option<O> {
|
||||
fn try_with_untracked<O>(
|
||||
&self,
|
||||
f: impl FnOnce(&Vec<Option<SendWrapper<T>>>) -> O,
|
||||
) -> Option<O> {
|
||||
match self {
|
||||
Self::Static(t) => Some(f(t)),
|
||||
Self::Dynamic(s) => s.try_with_untracked(f),
|
||||
|
@ -107,7 +112,7 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(value: T) -> Self {
|
||||
ElementsMaybeSignal::Static(vec![Some(value)])
|
||||
ElementsMaybeSignal::Static(vec![Some(SendWrapper::new(value))])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +121,7 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: Option<T>) -> Self {
|
||||
ElementsMaybeSignal::Static(vec![target])
|
||||
ElementsMaybeSignal::Static(vec![target.map(SendWrapper::new)])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +132,7 @@ macro_rules! impl_from_deref_option {
|
|||
E: From<$ty2> + 'static,
|
||||
{
|
||||
fn from(value: $ty) -> Self {
|
||||
Self::Static(vec![(*value).clone()])
|
||||
Self::Static(vec![(*value).clone().map(SendWrapper::new)])
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -185,7 +190,7 @@ macro_rules! impl_from_signal_string {
|
|||
let mut list = Vec::with_capacity(node_list.length() as usize);
|
||||
for i in 0..node_list.length() {
|
||||
let node = node_list.get(i).expect("checked the range");
|
||||
list.push(Some(node));
|
||||
list.push(Some(SendWrapper::new(node)));
|
||||
}
|
||||
list
|
||||
} else {
|
||||
|
@ -209,8 +214,8 @@ impl_from_signal_string!(Memo<String>);
|
|||
|
||||
impl_from_signal_string!(Signal<&str>);
|
||||
impl_from_signal_string!(ReadSignal<&str>);
|
||||
impl_from_signal_string!(RwSignal<&str>);
|
||||
impl_from_signal_string!(Memo<&str>);
|
||||
impl_from_signal_string!(RwSignal<&'static str>);
|
||||
impl_from_signal_string!(Memo<&'static str>);
|
||||
|
||||
// From single signal ///////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -227,10 +232,10 @@ macro_rules! impl_from_signal_option {
|
|||
};
|
||||
}
|
||||
|
||||
impl_from_signal_option!(Signal<Option<T>>);
|
||||
impl_from_signal_option!(ReadSignal<Option<T>>);
|
||||
impl_from_signal_option!(RwSignal<Option<T>>);
|
||||
impl_from_signal_option!(Memo<Option<T>>);
|
||||
impl_from_signal_option!(Signal<Option<SendWrapper<T>>>);
|
||||
impl_from_signal_option!(ReadSignal<Option<SendWrapper<T>>>);
|
||||
impl_from_signal_option!(RwSignal<Option<SendWrapper<T>>>);
|
||||
impl_from_signal_option!(Memo<Option<SendWrapper<T>>>);
|
||||
|
||||
macro_rules! impl_from_signal {
|
||||
($ty:ty) => {
|
||||
|
@ -245,10 +250,10 @@ macro_rules! impl_from_signal {
|
|||
};
|
||||
}
|
||||
|
||||
impl_from_signal!(Signal<T>);
|
||||
impl_from_signal!(ReadSignal<T>);
|
||||
impl_from_signal!(RwSignal<T>);
|
||||
impl_from_signal!(Memo<T>);
|
||||
impl_from_signal!(Signal<SendWrapper<T>>);
|
||||
impl_from_signal!(ReadSignal<SendWrapper<T>>);
|
||||
impl_from_signal!(RwSignal<SendWrapper<T>>);
|
||||
impl_from_signal!(Memo<SendWrapper<T>>);
|
||||
|
||||
// From single NodeRef //////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -257,13 +262,13 @@ macro_rules! impl_from_node_ref {
|
|||
impl<R> From<NodeRef<R>> for ElementsMaybeSignal<$ty, $ty>
|
||||
where
|
||||
R: ElementType + Clone + 'static,
|
||||
R::Output: JsCast + Into<$ty> + Clone + 'static,
|
||||
{
|
||||
fn from(node_ref: NodeRef<R>) -> Self {
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
vec![node_ref.get().map(move |el| {
|
||||
let el = el.into_any();
|
||||
let el: $ty = el.deref().clone().into();
|
||||
el
|
||||
let el: $ty = el.clone().into();
|
||||
SendWrapper::new(el)
|
||||
})]
|
||||
}))
|
||||
}
|
||||
|
@ -276,23 +281,23 @@ impl_from_node_ref!(web_sys::Element);
|
|||
|
||||
// From single leptos::html::HTMLElement ///////////////////////////////////////////
|
||||
|
||||
macro_rules! impl_from_html_element {
|
||||
($ty:ty) => {
|
||||
impl<E, At, Ch, Rndr> From<HtmlElement<E, At, Ch, Rndr>> for ElementsMaybeSignal<$ty, $ty>
|
||||
where
|
||||
E: ElementType,
|
||||
E::Output: std::ops::Deref<Target = $ty>,
|
||||
{
|
||||
fn from(value: HtmlElement<E, At, Ch, Rndr>) -> Self {
|
||||
let el: &$ty = value.deref();
|
||||
Self::Static(vec![Some(el.clone())])
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_html_element!(web_sys::EventTarget);
|
||||
impl_from_html_element!(web_sys::Element);
|
||||
// macro_rules! impl_from_html_element {
|
||||
// ($ty:ty) => {
|
||||
// impl<E, At, Ch, Rndr> From<HtmlElement<E, At, Ch, Rndr>> for ElementsMaybeSignal<$ty, $ty>
|
||||
// where
|
||||
// E: ElementType,
|
||||
// E::Output: std::ops::Deref<Target = $ty>,
|
||||
// {
|
||||
// fn from(value: HtmlElement<E, At, Ch, Rndr>) -> Self {
|
||||
// let el: &$ty = value.deref();
|
||||
// Self::Static(vec![Some(el.clone())])
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// impl_from_html_element!(web_sys::EventTarget);
|
||||
// impl_from_html_element!(web_sys::Element);
|
||||
|
||||
// From multiple static elements //////////////////////////////////////////////////////
|
||||
|
||||
|
@ -301,7 +306,12 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: &[T]) -> Self {
|
||||
Self::Static(target.iter().map(|t| Some(t.clone())).collect())
|
||||
Self::Static(
|
||||
target
|
||||
.iter()
|
||||
.map(|t| Some(SendWrapper::new(t.clone())))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +320,12 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: &[Option<T>]) -> Self {
|
||||
Self::Static(target.to_vec())
|
||||
Self::Static(
|
||||
target
|
||||
.iter()
|
||||
.map(|t| t.clone().map(SendWrapper::new))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +334,12 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: Vec<T>) -> Self {
|
||||
Self::Static(target.iter().map(|t| Some(t.clone())).collect())
|
||||
Self::Static(
|
||||
target
|
||||
.iter()
|
||||
.map(|t| Some(SendWrapper::new(t.clone())))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,7 +348,12 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: Vec<Option<T>>) -> Self {
|
||||
Self::Static(target.to_vec())
|
||||
Self::Static(
|
||||
target
|
||||
.into_iter()
|
||||
.map(|t| t.map(SendWrapper::new))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +362,12 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: [T; C]) -> Self {
|
||||
Self::Static(target.iter().map(|t| Some(t.clone())).collect())
|
||||
Self::Static(
|
||||
target
|
||||
.into_iter()
|
||||
.map(|t| Some(SendWrapper::new(t)))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,7 +376,12 @@ where
|
|||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: [Option<T>; C]) -> Self {
|
||||
Self::Static(target.to_vec())
|
||||
Self::Static(
|
||||
target
|
||||
.into_iter()
|
||||
.map(|t| t.map(SendWrapper::new))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,7 +392,7 @@ macro_rules! impl_from_strings_inner {
|
|||
Self::Static(
|
||||
$target
|
||||
.iter()
|
||||
.filter_map(|sel: &$str_ty| -> Option<Vec<Option<$el_ty>>> {
|
||||
.filter_map(|sel: &$str_ty| -> Option<Vec<Option<SendWrapper<$el_ty>>>> {
|
||||
cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
let _ = sel;
|
||||
None
|
||||
|
@ -368,7 +403,7 @@ macro_rules! impl_from_strings_inner {
|
|||
let mut list = Vec::with_capacity(node_list.length() as usize);
|
||||
for i in 0..node_list.length() {
|
||||
let node: $el_ty = node_list.get(i).expect("checked the range").unchecked_into();
|
||||
list.push(Some(node));
|
||||
list.push(Some(SendWrapper::new(node)));
|
||||
}
|
||||
|
||||
Some(list)
|
||||
|
@ -417,33 +452,33 @@ impl_from_strings!(web_sys::EventTarget, String);
|
|||
|
||||
// From signal of vec ////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<T, E> From<Signal<Vec<T>>> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E> From<Signal<Vec<SendWrapper<T>>>> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(signal: Signal<Vec<T>>) -> Self {
|
||||
fn from(signal: Signal<Vec<SendWrapper<T>>>) -> Self {
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
signal.get().into_iter().map(|t| Some(t)).collect()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> From<Signal<Vec<Option<T>>>> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E> From<Signal<Vec<Option<SendWrapper<T>>>>> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(target: Signal<Vec<Option<T>>>) -> Self {
|
||||
fn from(target: Signal<Vec<Option<SendWrapper<T>>>>) -> Self {
|
||||
Self::Dynamic(target)
|
||||
}
|
||||
}
|
||||
|
||||
// From multiple signals //////////////////////////////////////////////////////////////
|
||||
|
||||
impl<T, E> From<&[Signal<T>]> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E> From<&[Signal<SendWrapper<T>>]> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(list: &[Signal<T>]) -> Self {
|
||||
fn from(list: &[Signal<SendWrapper<T>>]) -> Self {
|
||||
let list = list.to_vec();
|
||||
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
|
@ -452,11 +487,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, E> From<&[Signal<Option<T>>]> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E> From<&[Signal<Option<SendWrapper<T>>>]> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(list: &[Signal<Option<T>>]) -> Self {
|
||||
fn from(list: &[Signal<Option<SendWrapper<T>>>]) -> Self {
|
||||
let list = list.to_vec();
|
||||
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
|
@ -465,11 +500,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, E> From<Vec<Signal<T>>> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E> From<Vec<Signal<SendWrapper<T>>>> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(list: Vec<Signal<T>>) -> Self {
|
||||
fn from(list: Vec<Signal<SendWrapper<T>>>) -> Self {
|
||||
let list = list.clone();
|
||||
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
|
@ -478,11 +513,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, E> From<Vec<Signal<Option<T>>>> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E> From<Vec<Signal<Option<SendWrapper<T>>>>> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(list: Vec<Signal<Option<T>>>) -> Self {
|
||||
fn from(list: Vec<Signal<Option<SendWrapper<T>>>>) -> Self {
|
||||
let list = list.clone();
|
||||
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
|
@ -491,11 +526,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, E, const C: usize> From<[Signal<T>; C]> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E, const C: usize> From<[Signal<SendWrapper<T>>; C]> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(list: [Signal<T>; C]) -> Self {
|
||||
fn from(list: [Signal<SendWrapper<T>>; C]) -> Self {
|
||||
let list = list.to_vec();
|
||||
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
|
@ -504,11 +539,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, E, const C: usize> From<[Signal<Option<T>>; C]> for ElementsMaybeSignal<T, E>
|
||||
impl<T, E, const C: usize> From<[Signal<Option<SendWrapper<T>>>; C]> for ElementsMaybeSignal<T, E>
|
||||
where
|
||||
T: Into<E> + Clone + 'static,
|
||||
{
|
||||
fn from(list: [Signal<Option<T>>; C]) -> Self {
|
||||
fn from(list: [Signal<Option<SendWrapper<T>>>; C]) -> Self {
|
||||
let list = list.to_vec();
|
||||
|
||||
Self::Dynamic(Signal::derive(move || {
|
||||
|
@ -526,9 +561,8 @@ macro_rules! impl_from_multi_node_ref_inner {
|
|||
.iter()
|
||||
.map(|node_ref| {
|
||||
node_ref.get().map(move |el| {
|
||||
let el = el.into_any();
|
||||
let el: $ty = el.deref().clone().into();
|
||||
el
|
||||
let el: $ty = el.clone().into();
|
||||
SendWrapper::new(el)
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
@ -541,6 +575,7 @@ macro_rules! impl_from_multi_node_ref {
|
|||
impl<R> From<&[NodeRef<R>]> for ElementsMaybeSignal<$ty, $ty>
|
||||
where
|
||||
R: ElementType + Clone + 'static,
|
||||
R::Output: JsCast + Into<$ty> + Clone + 'static,
|
||||
{
|
||||
fn from(node_refs: &[NodeRef<R>]) -> Self {
|
||||
let node_refs = node_refs.to_vec();
|
||||
|
@ -551,6 +586,7 @@ macro_rules! impl_from_multi_node_ref {
|
|||
impl<R, const C: usize> From<[NodeRef<R>; C]> for ElementsMaybeSignal<$ty, $ty>
|
||||
where
|
||||
R: ElementType + Clone + 'static,
|
||||
R::Output: JsCast + Into<$ty> + Clone + 'static,
|
||||
{
|
||||
fn from(node_refs: [NodeRef<R>; C]) -> Self {
|
||||
let node_refs = node_refs.to_vec();
|
||||
|
@ -561,6 +597,7 @@ macro_rules! impl_from_multi_node_ref {
|
|||
impl<R> From<Vec<NodeRef<R>>> for ElementsMaybeSignal<$ty, $ty>
|
||||
where
|
||||
R: ElementType + Clone + 'static,
|
||||
R::Output: JsCast + Into<$ty> + Clone + 'static,
|
||||
{
|
||||
fn from(node_refs: Vec<NodeRef<R>>) -> Self {
|
||||
let node_refs = node_refs.clone();
|
||||
|
|
|
@ -50,26 +50,38 @@ impl<T> From<Signal<T>> for MaybeRwSignal<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> From<ReadSignal<T>> for MaybeRwSignal<T> {
|
||||
impl<T> From<ReadSignal<T>> for MaybeRwSignal<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
fn from(s: ReadSignal<T>) -> Self {
|
||||
Self::DynamicRead(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Memo<T>> for MaybeRwSignal<T> {
|
||||
impl<T> From<Memo<T>> for MaybeRwSignal<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
fn from(s: Memo<T>) -> Self {
|
||||
Self::DynamicRead(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<RwSignal<T>> for MaybeRwSignal<T> {
|
||||
impl<T> From<RwSignal<T>> for MaybeRwSignal<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
fn from(s: RwSignal<T>) -> Self {
|
||||
let (r, w) = s.split();
|
||||
Self::DynamicRw(r.into(), w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<(ReadSignal<T>, WriteSignal<T>)> for MaybeRwSignal<T> {
|
||||
impl<T> From<(ReadSignal<T>, WriteSignal<T>)> for MaybeRwSignal<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
fn from(s: (ReadSignal<T>, WriteSignal<T>)) -> Self {
|
||||
Self::DynamicRw(s.0.into(), s.1)
|
||||
}
|
||||
|
@ -87,7 +99,10 @@ impl From<&str> for MaybeRwSignal<String> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> MaybeRwSignal<T> {
|
||||
impl<T: Clone> MaybeRwSignal<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
pub fn into_signal(self) -> (Signal<T>, WriteSignal<T>) {
|
||||
match self {
|
||||
Self::DynamicRead(s) => {
|
||||
|
|
|
@ -22,7 +22,7 @@ where
|
|||
|
||||
impl<T> Default for UseRwSignal<T>
|
||||
where
|
||||
T: Default,
|
||||
T: Default + Send + Sync,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::Combined(Default::default())
|
||||
|
@ -47,7 +47,10 @@ impl<T> DefinedAt for UseRwSignal<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> With for UseRwSignal<T> {
|
||||
impl<T> With for UseRwSignal<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
type Value = T;
|
||||
|
||||
fn with<R>(&self, f: impl FnOnce(&T) -> R) -> R {
|
||||
|
@ -65,7 +68,10 @@ impl<T> With for UseRwSignal<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> WithUntracked for UseRwSignal<T> {
|
||||
impl<T> WithUntracked for UseRwSignal<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
type Value = T;
|
||||
|
||||
fn with_untracked<R>(&self, f: impl FnOnce(&T) -> R) -> R {
|
||||
|
|
|
@ -25,11 +25,11 @@ mod is_none;
|
|||
mod is_ok;
|
||||
mod is_some;
|
||||
mod on_click_outside;
|
||||
mod use_user_media;
|
||||
mod signal_debounced;
|
||||
mod signal_throttled;
|
||||
mod sync_signal;
|
||||
mod use_active_element;
|
||||
mod use_user_media;
|
||||
// mod use_active_element;
|
||||
mod use_breakpoints;
|
||||
mod use_broadcast_channel;
|
||||
mod use_color_mode;
|
||||
|
@ -91,11 +91,11 @@ pub use is_none::*;
|
|||
pub use is_ok::*;
|
||||
pub use is_some::*;
|
||||
pub use on_click_outside::*;
|
||||
pub use use_user_media::*;
|
||||
pub use signal_debounced::*;
|
||||
pub use signal_throttled::*;
|
||||
pub use sync_signal::*;
|
||||
pub use use_active_element::*;
|
||||
pub use use_user_media::*;
|
||||
// pub use use_active_element::*;
|
||||
pub use use_breakpoints::*;
|
||||
pub use use_broadcast_channel::*;
|
||||
pub use use_color_mode::*;
|
||||
|
|
|
@ -7,9 +7,9 @@ macro_rules! use_partial_cmp {
|
|||
pub fn $fn_name<C, S, N>(container: S) -> Signal<Option<N>>
|
||||
where
|
||||
S: Into<MaybeSignal<C>>,
|
||||
C: 'static,
|
||||
C: Send + Sync + 'static,
|
||||
for<'a> &'a C: IntoIterator<Item = &'a N>,
|
||||
N: PartialOrd + Clone,
|
||||
N: PartialOrd + Clone + Send + Sync,
|
||||
{
|
||||
let container = container.into();
|
||||
|
||||
|
@ -47,8 +47,8 @@ macro_rules! use_simple_math {
|
|||
$(#[$outer])*
|
||||
pub fn [<use_ $fn_name>]<S, N>(x: S) -> Signal<N>
|
||||
where
|
||||
S: Into<MaybeSignal<N>>,
|
||||
N: Float,
|
||||
S: Into<MaybeSignal<N>> + Send + Sync,
|
||||
N: Float + Send + Sync,
|
||||
{
|
||||
let x = x.into();
|
||||
Signal::derive(move || x.get().$fn_name())
|
||||
|
|
|
@ -148,7 +148,7 @@ pub fn sync_signal<T>(
|
|||
right: impl Into<UseRwSignal<T>>,
|
||||
) -> impl Fn() + Clone
|
||||
where
|
||||
T: Clone + PartialEq + 'static,
|
||||
T: Clone + PartialEq + Send + Sync + 'static,
|
||||
{
|
||||
sync_signal_with_options(left, right, SyncSignalOptions::default())
|
||||
}
|
||||
|
@ -160,8 +160,8 @@ pub fn sync_signal_with_options<L, R>(
|
|||
options: SyncSignalOptions<L, R>,
|
||||
) -> impl Fn() + Clone
|
||||
where
|
||||
L: Clone + PartialEq + 'static,
|
||||
R: Clone + PartialEq + 'static,
|
||||
L: Clone + PartialEq + Send + Sync + 'static,
|
||||
R: Clone + PartialEq + Send + Sync + 'static,
|
||||
{
|
||||
let SyncSignalOptions {
|
||||
immediate,
|
||||
|
|
|
@ -110,7 +110,7 @@ use std::hash::Hash;
|
|||
///
|
||||
/// Since internally this uses [`use_media_query`], which returns always `false` on the server,
|
||||
/// the returned methods also will return `false`.
|
||||
pub fn use_breakpoints<K: Eq + Hash + Debug + Clone>(
|
||||
pub fn use_breakpoints<K: Eq + Hash + Debug + Clone + Send + Sync>(
|
||||
breakpoints: HashMap<K, u32>,
|
||||
) -> UseBreakpointsReturn<K> {
|
||||
UseBreakpointsReturn { breakpoints }
|
||||
|
@ -118,7 +118,7 @@ pub fn use_breakpoints<K: Eq + Hash + Debug + Clone>(
|
|||
|
||||
/// Return type of [`use_breakpoints`]
|
||||
#[derive(Clone)]
|
||||
pub struct UseBreakpointsReturn<K: Eq + Hash + Debug + Clone> {
|
||||
pub struct UseBreakpointsReturn<K: Eq + Hash + Debug + Clone + Send + Sync> {
|
||||
breakpoints: HashMap<K, u32>,
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ macro_rules! impl_cmp_reactively {
|
|||
};
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash + Debug + Clone> UseBreakpointsReturn<K> {
|
||||
impl<K: Eq + Hash + Debug + Clone + Send + Sync> UseBreakpointsReturn<K> {
|
||||
fn match_(query: &str) -> bool {
|
||||
if let Ok(Some(query_list)) = use_window().match_media(query) {
|
||||
return query_list.matches();
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
|||
use codee::{CodecError, Decoder, Encoder};
|
||||
use leptos::ev::messageerror;
|
||||
use leptos::prelude::*;
|
||||
use send_wrapper::SendWrapper;
|
||||
use thiserror::Error;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
|
@ -80,12 +81,15 @@ pub fn use_broadcast_channel<T, C>(
|
|||
<C as Decoder<T>>::Error,
|
||||
>
|
||||
where
|
||||
T: Send + Sync,
|
||||
C: Encoder<T, Encoded = String> + Decoder<T, Encoded = str>,
|
||||
<C as Encoder<T>>::Error: Send + Sync,
|
||||
<C as Decoder<T>>::Error: Send + Sync,
|
||||
{
|
||||
let is_supported = use_supported(|| js!("BroadcastChannel" in &window()));
|
||||
|
||||
let (is_closed, set_closed) = signal(false);
|
||||
let (channel, set_channel) = signal(None::<web_sys::BroadcastChannel>);
|
||||
let (channel, set_channel) = signal(None::<SendWrapper<web_sys::BroadcastChannel>>);
|
||||
let (message, set_message) = signal(None::<T>);
|
||||
let (error, set_error) = signal(
|
||||
None::<UseBroadcastChannelError<<C as Encoder<T>>::Error, <C as Decoder<T>>::Error>>,
|
||||
|
@ -99,7 +103,9 @@ where
|
|||
channel
|
||||
.post_message(&msg.into())
|
||||
.map_err(|err| {
|
||||
set_error.set(Some(UseBroadcastChannelError::PostMessage(err)))
|
||||
set_error.set(Some(UseBroadcastChannelError::PostMessage(
|
||||
SendWrapper::new(err),
|
||||
)))
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
@ -124,7 +130,7 @@ where
|
|||
|
||||
if is_supported.get_untracked() {
|
||||
let channel_val = web_sys::BroadcastChannel::new(name).ok();
|
||||
set_channel.set(channel_val.clone());
|
||||
set_channel.set(channel_val.clone().map(SendWrapper::new));
|
||||
|
||||
if let Some(channel) = channel_val {
|
||||
let _ = use_event_listener_with_options(
|
||||
|
@ -151,7 +157,9 @@ where
|
|||
channel.clone(),
|
||||
messageerror,
|
||||
move |event| {
|
||||
set_error.set(Some(UseBroadcastChannelError::MessageEvent(event)));
|
||||
set_error.set(Some(UseBroadcastChannelError::MessageEvent(
|
||||
SendWrapper::new(event),
|
||||
)));
|
||||
},
|
||||
UseEventListenerOptions::default().passive(true),
|
||||
);
|
||||
|
@ -188,7 +196,7 @@ where
|
|||
pub is_supported: Signal<bool>,
|
||||
|
||||
/// The broadcast channel that is wrapped by this function
|
||||
pub channel: Signal<Option<web_sys::BroadcastChannel>>,
|
||||
pub channel: Signal<Option<SendWrapper<web_sys::BroadcastChannel>>>,
|
||||
|
||||
/// Latest message received from the channel
|
||||
pub message: Signal<Option<T>>,
|
||||
|
@ -209,9 +217,9 @@ where
|
|||
#[derive(Debug, Error)]
|
||||
pub enum UseBroadcastChannelError<E, D> {
|
||||
#[error("failed to post message")]
|
||||
PostMessage(JsValue),
|
||||
PostMessage(SendWrapper<JsValue>),
|
||||
#[error("channel message error")]
|
||||
MessageEvent(web_sys::MessageEvent),
|
||||
MessageEvent(SendWrapper<web_sys::MessageEvent>),
|
||||
#[error("failed to (de)encode value")]
|
||||
Codec(CodecError<E, D>),
|
||||
#[error("received value is not a string")]
|
||||
|
|
|
@ -36,10 +36,10 @@ use leptos::prelude::wrappers::read::Signal;
|
|||
pub fn use_device_orientation() -> UseDeviceOrientationReturn {
|
||||
cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
let is_supported = Signal::derive(|| false);
|
||||
let absolute = || false;
|
||||
let alpha = || None;
|
||||
let beta = || None;
|
||||
let gamma = || None;
|
||||
let absolute = Signal::derive(|| false);
|
||||
let alpha = Signal::derive(|| None);
|
||||
let beta = Signal::derive(|| None);
|
||||
let gamma = Signal::derive(|| None);
|
||||
} else {
|
||||
use leptos::prelude::*;
|
||||
use crate::{use_event_listener_with_options, UseEventListenerOptions, use_supported, js};
|
||||
|
|
|
@ -5,8 +5,9 @@ use leptos::ev::{pointerdown, pointermove, pointerup};
|
|||
use leptos::prelude::diagnostics::SpecialNonReactiveZone;
|
||||
use leptos::prelude::wrappers::read::Signal;
|
||||
use leptos::prelude::*;
|
||||
use send_wrapper::SendWrapper;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::PointerEvent;
|
||||
|
||||
|
@ -92,11 +93,12 @@ where
|
|||
let target = target.into();
|
||||
|
||||
let dragging_handle = if let Some(handle) = handle {
|
||||
let handle = (handle).into();
|
||||
Signal::derive(move || handle.get().map(|handle| handle.into()))
|
||||
// let handle = Signal::derive(|| SendWrapper::new(handle));
|
||||
let handle: ElementMaybeSignal<_, _> = handle.into();
|
||||
Signal::derive(move || handle.get().map(|handle| SendWrapper::new(handle.into())))
|
||||
} else {
|
||||
let target = target.clone();
|
||||
Signal::derive(move || target.get().map(|target| target.into()))
|
||||
Signal::derive(move || target.get().map(|target| SendWrapper::new(target.into())))
|
||||
};
|
||||
|
||||
let (position, set_position) = initial_value.into_signal();
|
||||
|
@ -280,13 +282,13 @@ where
|
|||
initial_value: MaybeRwSignal<Position>,
|
||||
|
||||
/// Callback when the dragging starts. Return `false` to prevent dragging.
|
||||
on_start: Rc<dyn Fn(UseDraggableCallbackArgs) -> bool>,
|
||||
on_start: Arc<dyn Fn(UseDraggableCallbackArgs) -> bool + Send + Sync>,
|
||||
|
||||
/// Callback during dragging.
|
||||
on_move: Rc<dyn Fn(UseDraggableCallbackArgs)>,
|
||||
on_move: Arc<dyn Fn(UseDraggableCallbackArgs) + Send + Sync>,
|
||||
|
||||
/// Callback when dragging end.
|
||||
on_end: Rc<dyn Fn(UseDraggableCallbackArgs)>,
|
||||
on_end: Arc<dyn Fn(UseDraggableCallbackArgs) + Send + Sync>,
|
||||
|
||||
#[builder(skip)]
|
||||
_marker1: PhantomData<DragT>,
|
||||
|
@ -306,9 +308,9 @@ impl Default
|
|||
handle: None,
|
||||
pointer_types: vec![PointerType::Mouse, PointerType::Touch, PointerType::Pen],
|
||||
initial_value: MaybeRwSignal::default(),
|
||||
on_start: Rc::new(|_| true),
|
||||
on_move: Rc::new(|_| {}),
|
||||
on_end: Rc::new(|_| {}),
|
||||
on_start: Arc::new(|_| true),
|
||||
on_move: Arc::new(|_| {}),
|
||||
on_end: Arc::new(|_| {}),
|
||||
_marker1: PhantomData,
|
||||
_marker2: PhantomData,
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@ use cfg_if::cfg_if;
|
|||
use default_struct_builder::DefaultBuilder;
|
||||
use leptos::prelude::wrappers::read::Signal;
|
||||
use leptos::prelude::*;
|
||||
use send_wrapper::SendWrapper;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
cfg_if! { if #[cfg(not(feature = "ssr"))] {
|
||||
use crate::use_event_listener;
|
||||
|
@ -73,7 +74,7 @@ where
|
|||
T: Into<web_sys::EventTarget> + Clone + 'static,
|
||||
{
|
||||
let (is_over_drop_zone, set_over_drop_zone) = signal(false);
|
||||
let (files, set_files) = signal(Vec::<web_sys::File>::new());
|
||||
let (files, set_files) = signal(Vec::<SendWrapper<web_sys::File>>::new());
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
{
|
||||
|
@ -176,22 +177,22 @@ where
|
|||
#[cfg_attr(feature = "ssr", allow(dead_code))]
|
||||
pub struct UseDropZoneOptions {
|
||||
/// Event handler for the [`drop`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drop_event) event
|
||||
on_drop: Rc<dyn Fn(UseDropZoneEvent)>,
|
||||
on_drop: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>,
|
||||
/// Event handler for the [`dragenter`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragenter_event) event
|
||||
on_enter: Rc<dyn Fn(UseDropZoneEvent)>,
|
||||
on_enter: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>,
|
||||
/// Event handler for the [`dragleave`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragleave_event) event
|
||||
on_leave: Rc<dyn Fn(UseDropZoneEvent)>,
|
||||
on_leave: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>,
|
||||
/// Event handler for the [`dragover`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragover_event) event
|
||||
on_over: Rc<dyn Fn(UseDropZoneEvent)>,
|
||||
on_over: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>,
|
||||
}
|
||||
|
||||
impl Default for UseDropZoneOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
on_drop: Rc::new(|_| {}),
|
||||
on_enter: Rc::new(|_| {}),
|
||||
on_leave: Rc::new(|_| {}),
|
||||
on_over: Rc::new(|_| {}),
|
||||
on_drop: Arc::new(|_| {}),
|
||||
on_enter: Arc::new(|_| {}),
|
||||
on_leave: Arc::new(|_| {}),
|
||||
on_over: Arc::new(|_| {}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +215,7 @@ pub struct UseDropZoneEvent {
|
|||
/// Return type of [`use_drop_zone`].
|
||||
pub struct UseDropZoneReturn {
|
||||
/// Files being handled
|
||||
pub files: Signal<Vec<web_sys::File>>,
|
||||
pub files: Signal<Vec<SendWrapper<web_sys::File>>>,
|
||||
/// Whether the files (dragged by the pointer) are over the drop zone
|
||||
pub is_over_drop_zone: Signal<bool>,
|
||||
}
|
||||
|
|
|
@ -259,9 +259,9 @@ where
|
|||
for event_name in named_events.clone() {
|
||||
let _ = use_event_listener(
|
||||
es.clone(),
|
||||
leptos::ev::Custom::<ev::Event>::new(event_name),
|
||||
leptos::ev::Custom::<leptos::ev::Event>::new(event_name),
|
||||
move |e| {
|
||||
set_event.set(Some(e.clone()));
|
||||
set_event.set(Some(SendWrapper::new(e.clone())));
|
||||
let data_string = js!(e["data"]).ok().and_then(|d| d.as_string());
|
||||
set_data_from_string(data_string);
|
||||
},
|
||||
|
|
|
@ -303,9 +303,11 @@ where
|
|||
Some(Arc::new(move || {
|
||||
if !manually_closed_ref.get_value()
|
||||
&& !reconnect_limit.is_exceeded_by(reconnect_times_ref.get_value())
|
||||
&& ws_ref.get_value().map_or(false, |ws: SendWrapper<WebSocket>| {
|
||||
ws.ready_state() != WebSocket::OPEN
|
||||
})
|
||||
&& ws_ref
|
||||
.get_value()
|
||||
.map_or(false, |ws: SendWrapper<WebSocket>| {
|
||||
ws.ready_state() != WebSocket::OPEN
|
||||
})
|
||||
{
|
||||
reconnect_timer_ref.set_value(
|
||||
set_timeout_with_handle(
|
||||
|
@ -417,7 +419,7 @@ where
|
|||
on_message(&val);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
drop(zone);
|
||||
drop(zone);
|
||||
|
||||
set_message.set(Some(val));
|
||||
}
|
||||
|
@ -628,7 +630,7 @@ impl ReconnectLimit {
|
|||
}
|
||||
}
|
||||
|
||||
type ArcFnBytes = Arc<dyn Fn(&[u8])>;
|
||||
type ArcFnBytes = Arc<dyn Fn(&[u8]) + Send + Sync>;
|
||||
|
||||
/// Options for [`use_websocket_with_options`].
|
||||
#[derive(DefaultBuilder)]
|
||||
|
@ -644,7 +646,7 @@ where
|
|||
/// `WebSocket` message callback for text.
|
||||
on_message_raw: Arc<dyn Fn(&str) + Send + Sync>,
|
||||
/// `WebSocket` message callback for binary.
|
||||
on_message_raw_bytes: ArcFnBytes + Send + Sync,
|
||||
on_message_raw_bytes: ArcFnBytes,
|
||||
/// `WebSocket` error callback.
|
||||
#[builder(skip)]
|
||||
on_error: Arc<dyn Fn(UseWebSocketError<E, D>) + Send + Sync>,
|
||||
|
|
|
@ -15,7 +15,7 @@ macro_rules! signal_filtered {
|
|||
) -> Signal<T>
|
||||
where
|
||||
S: Into<Signal<T>>,
|
||||
T: Clone + 'static,
|
||||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
[<signal_ $filter_name d_with_options>](value, ms, [<$filter_name:camel Options>]::default())
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ macro_rules! signal_filtered {
|
|||
) -> Signal<T>
|
||||
where
|
||||
S: Into<Signal<T>>,
|
||||
T: Clone + 'static,
|
||||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
let value = value.into();
|
||||
let ms = ms.into();
|
||||
|
|
Loading…
Add table
Reference in a new issue