diff --git a/.idea/leptos-use.iml b/.idea/leptos-use.iml
index 8da99c2..a07bd8b 100644
--- a/.idea/leptos-use.iml
+++ b/.idea/leptos-use.iml
@@ -63,6 +63,11 @@
+
+
+
+
+
@@ -133,4 +138,4 @@
-
+
\ No newline at end of file
diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md
index 6ca246a..45d96ad 100644
--- a/docs/book/src/SUMMARY.md
+++ b/docs/book/src/SUMMARY.md
@@ -61,7 +61,7 @@
# Network
- [use_websocket](network/use_websocket.md)
-- [use_webtransport](network/use_webtransport.md)
+
# Animation
diff --git a/examples/use_broadcast_channel/Cargo.toml b/examples/use_broadcast_channel/Cargo.toml
index d8414a1..6a95089 100644
--- a/examples/use_broadcast_channel/Cargo.toml
+++ b/examples/use_broadcast_channel/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-leptos = { version = "0.5", features = ["nightly", "csr"] }
+leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
diff --git a/examples/use_broadcast_channel/src/main.rs b/examples/use_broadcast_channel/src/main.rs
index 651183c..749ae88 100644
--- a/examples/use_broadcast_channel/src/main.rs
+++ b/examples/use_broadcast_channel/src/main.rs
@@ -1,13 +1,56 @@
use leptos::*;
use leptos_use::docs::demo_or_body;
-use leptos_use::use_broadcast_channel;
+use leptos_use::utils::FromToStringCodec;
+use leptos_use::{use_broadcast_channel, UseBroadcastChannelReturn};
#[component]
fn Demo() -> impl IntoView {
+ let UseBroadcastChannelReturn {
+ is_supported,
+ message,
+ post,
+ error,
+ ..
+ } = use_broadcast_channel::("leptos-use-demo-channel");
- use_broadcast_channel();
+ let (input_value, set_input_value) = create_signal(String::new());
- view! { }
+ view! {
+ Please open this page in at least two tabs
+
+ "BroadcastChannel not supported"
}
+ >
+
+
+
+ "Received message: " {move || message().as_ref().unwrap().to_string()}
+
+
+
+ "Error: " {move || format!("{:?}", error().as_ref().unwrap())}
+
+
+ }
}
fn main() {
diff --git a/examples/use_webtransport/Cargo.toml b/examples/use_webtransport/Cargo.toml
index f629f2d..5291647 100644
--- a/examples/use_webtransport/Cargo.toml
+++ b/examples/use_webtransport/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-leptos = { version = "0.5.0-beta2", features = ["nightly", "csr"] }
+leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
diff --git a/examples/use_webtransport_with_server/client/Cargo.toml b/examples/use_webtransport_with_server/client/Cargo.toml
index 5632fa1..a6a7279 100644
--- a/examples/use_webtransport_with_server/client/Cargo.toml
+++ b/examples/use_webtransport_with_server/client/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-leptos = { version = "0.5.0-rc1", features = ["nightly", "csr"] }
+leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
diff --git a/src/lib.rs b/src/lib.rs
index 6471119..5bb089e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,21 +9,21 @@ pub mod math;
pub mod storage;
pub mod utils;
-cfg_if! { if #[cfg(web_sys_unstable_apis)] {
- mod use_webtransport;
- pub use use_webtransport::*;
-}}
+#[cfg(web_sys_unstable_apis)]
+mod use_webtransport;
+#[cfg(web_sys_unstable_apis)]
+pub use use_webtransport::*;
mod is_err;
mod is_none;
mod is_ok;
mod is_some;
mod on_click_outside;
-mod use_broadcast_channel;
mod signal_debounced;
mod signal_throttled;
mod use_active_element;
mod use_breakpoints;
+mod use_broadcast_channel;
mod use_color_mode;
mod use_cookie;
mod use_css_var;
@@ -79,11 +79,11 @@ pub use is_none::*;
pub use is_ok::*;
pub use is_some::*;
pub use on_click_outside::*;
-pub use use_broadcast_channel::*;
pub use signal_debounced::*;
pub use signal_throttled::*;
pub use use_active_element::*;
pub use use_breakpoints::*;
+pub use use_broadcast_channel::*;
pub use use_color_mode::*;
pub use use_cookie::*;
pub use use_css_var::*;
@@ -125,7 +125,6 @@ pub use use_timestamp::*;
pub use use_to_string::*;
pub use use_web_notification::*;
pub use use_websocket::*;
-pub use use_webtransport::*;
pub use use_window::*;
pub use use_window_focus::*;
pub use use_window_scroll::*;
diff --git a/src/storage/mod.rs b/src/storage/mod.rs
index b3b9487..54f79db 100644
--- a/src/storage/mod.rs
+++ b/src/storage/mod.rs
@@ -3,11 +3,6 @@ mod use_session_storage;
mod use_storage;
pub use crate::core::StorageType;
-#[cfg(feature = "serde")]
-pub use codec_json::*;
-#[cfg(feature = "prost")]
-pub use codec_prost::*;
-pub use codec_string::*;
pub use use_local_storage::*;
pub use use_session_storage::*;
pub use use_storage::*;
diff --git a/src/storage/use_local_storage.rs b/src/storage/use_local_storage.rs
index 4479a4a..f1b546d 100644
--- a/src/storage/use_local_storage.rs
+++ b/src/storage/use_local_storage.rs
@@ -1,4 +1,5 @@
-use super::{use_storage_with_options, Codec, StorageType, UseStorageOptions};
+use super::{use_storage_with_options, StorageType, UseStorageOptions};
+use crate::utils::StringCodec;
use leptos::signal_prelude::*;
/// Reactive [LocalStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).
@@ -14,7 +15,7 @@ pub fn use_local_storage(
) -> (Signal, WriteSignal, impl Fn() + Clone)
where
T: Clone + Default + PartialEq,
- C: Codec + Default,
+ C: StringCodec + Default,
{
use_storage_with_options(
StorageType::Local,
@@ -30,7 +31,7 @@ pub fn use_local_storage_with_options(
) -> (Signal, WriteSignal, impl Fn() + Clone)
where
T: Clone + PartialEq,
- C: Codec,
+ C: StringCodec,
{
use_storage_with_options(StorageType::Local, key, options)
}
diff --git a/src/storage/use_session_storage.rs b/src/storage/use_session_storage.rs
index 127e457..6d2a215 100644
--- a/src/storage/use_session_storage.rs
+++ b/src/storage/use_session_storage.rs
@@ -1,4 +1,5 @@
-use super::{use_storage_with_options, Codec, StorageType, UseStorageOptions};
+use super::{use_storage_with_options, StorageType, UseStorageOptions};
+use crate::utils::StringCodec;
use leptos::signal_prelude::*;
/// Reactive [SessionStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage).
@@ -14,7 +15,7 @@ pub fn use_session_storage(
) -> (Signal, WriteSignal, impl Fn() + Clone)
where
T: Clone + Default + PartialEq,
- C: Codec + Default,
+ C: StringCodec + Default,
{
use_storage_with_options(
StorageType::Session,
@@ -30,7 +31,7 @@ pub fn use_session_storage_with_options(
) -> (Signal, WriteSignal, impl Fn() + Clone)
where
T: Clone + PartialEq,
- C: Codec,
+ C: StringCodec,
{
use_storage_with_options(StorageType::Session, key, options)
}
diff --git a/src/storage/use_storage.rs b/src/storage/use_storage.rs
index af94564..a87f475 100644
--- a/src/storage/use_storage.rs
+++ b/src/storage/use_storage.rs
@@ -1,3 +1,4 @@
+use crate::utils::FromToStringCodec;
use crate::{
core::{MaybeRwSignal, StorageType},
utils::{FilterOptions, StringCodec},
@@ -28,18 +29,19 @@ const INTERNAL_STORAGE_EVENT: &str = "leptos-use-storage";
///
/// ```
/// # use leptos::*;
-/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage_with_options, UseStorageOptions, StringCodec, JsonCodec, ProstCodec};
+/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage_with_options, UseStorageOptions};
/// # use serde::{Deserialize, Serialize};
+/// # use leptos_use::utils::{FromToStringCodec, JsonCodec, ProstCodec};
/// #
/// # pub fn Demo() -> impl IntoView {
/// // Binds a struct:
/// let (state, set_state, _) = use_local_storage::("my-state");
///
/// // Binds a bool, stored as a string:
-/// let (flag, set_flag, remove_flag) = use_session_storage::("my-flag");
+/// let (flag, set_flag, remove_flag) = use_session_storage::("my-flag");
///
/// // Binds a number, stored as a string:
-/// let (count, set_count, _) = use_session_storage::("my-count");
+/// let (count, set_count, _) = use_session_storage::("my-count");
/// // Binds a number, stored in JSON:
/// let (count, set_count, _) = use_session_storage::("my-count-kept-in-js");
///
@@ -89,7 +91,11 @@ pub fn use_storage(
storage_type: StorageType,
key: impl AsRef,
) -> (Signal, WriteSignal, impl Fn() + Clone) {
- use_storage_with_options::(storage_type, key, UseStorageOptions::default())
+ use_storage_with_options::(
+ storage_type,
+ key,
+ UseStorageOptions::default(),
+ )
}
/// Version of [`use_storage`] that accepts [`UseStorageOptions`].
@@ -100,7 +106,7 @@ pub fn use_storage_with_options(
) -> (Signal, WriteSignal, impl Fn() + Clone)
where
T: Clone + PartialEq,
- C: Codec,
+ C: StringCodec,
{
let UseStorageOptions {
codec,
@@ -322,7 +328,7 @@ pub enum UseStorageError {
}
/// Options for use with [`use_local_storage_with_options`], [`use_session_storage_with_options`] and [`use_storage_with_options`].
-pub struct UseStorageOptions> {
+pub struct UseStorageOptions> {
// Translates to and from UTF-16 strings
codec: C,
// Callback for when an error occurs
@@ -344,7 +350,7 @@ fn handle_error(
result.map_err(|err| (on_error)(err))
}
-impl + Default> Default for UseStorageOptions {
+impl + Default> Default for UseStorageOptions {
fn default() -> Self {
Self {
codec: C::default(),
@@ -356,7 +362,7 @@ impl + Default> Default for UseStorageOptions {
}
}
-impl> UseStorageOptions {
+impl> UseStorageOptions {
/// Sets the codec to use for encoding and decoding values to and from UTF-16 strings.
pub fn codec(self, codec: impl Into) -> Self {
Self {
diff --git a/src/use_broadcast_channel.rs b/src/use_broadcast_channel.rs
index 49b250a..af70b4a 100644
--- a/src/use_broadcast_channel.rs
+++ b/src/use_broadcast_channel.rs
@@ -1,9 +1,14 @@
-use crate::storage::Codec;
-use crate::use_supported;
-use default_struct_builder::DefaultBuilder;
+use crate::utils::StringCodec;
+use crate::{
+ use_event_listener, use_event_listener_with_options, use_supported, UseEventListenerOptions,
+};
use leptos::*;
+use thiserror::Error;
+use wasm_bindgen::JsValue;
+/// Reactive [BroadcastChannel API](https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel).
///
+/// Closes a broadcast channel automatically when the component is cleaned up.
///
/// ## Demo
///
@@ -11,59 +16,194 @@ use leptos::*;
///
/// ## Usage
///
+/// The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames, or iframes) of the same origin.
+///
+/// Messages are broadcasted via a message event fired at all BroadcastChannel objects listening to the channel.
+///
/// ```
/// # use leptos::*;
-/// # use leptos_use::use_broadcast_channel;
+/// # use leptos_use::{use_broadcast_channel, UseBroadcastChannelReturn};
+/// # use leptos_use::utils::FromToStringCodec;
/// #
/// # #[component]
/// # fn Demo() -> impl IntoView {
-/// use_broadcast_channel();
+/// let UseBroadcastChannelReturn {
+/// is_supported,
+/// message,
+/// post,
+/// error,
+/// close,
+/// ..
+/// } = use_broadcast_channel::("some-channel-name");
+///
+/// post(&true);
+///
+/// close();
/// #
/// # view! { }
/// # }
/// ```
-pub fn use_broadcast_channel(name: &str) -> UseBroadcastChannelReturn
+///
+/// Just like with [`use_storage`] you can use different codecs for encoding and decoding.
+///
+/// ```
+/// # use leptos::*;
+/// # use serde::{Deserialize, Serialize};
+/// # use leptos_use::use_broadcast_channel;
+/// # use leptos_use::utils::JsonCodec;
+/// #
+/// // Data sent in JSON must implement Serialize, Deserialize:
+/// #[derive(Serialize, Deserialize, Clone, PartialEq)]
+/// pub struct MyState {
+/// pub playing_lego: bool,
+/// pub everything_is_awesome: String,
+/// }
+///
+/// # #[component]
+/// # fn Demo() -> impl IntoView {
+/// use_broadcast_channel::("everyting-is-awesome");
+/// # view! { }
+/// # }
+/// ```
+pub fn use_broadcast_channel(
+ name: &str,
+) -> UseBroadcastChannelReturn
where
- C: Codec + Default + Clone,
+ C: StringCodec + Default + Clone,
{
let is_supported = use_supported(|| JsValue::from("BroadcastChannel").js_in(&window()));
let (is_closed, set_closed) = create_signal(false);
let (channel, set_channel) = create_signal(None::);
let (message, set_message) = create_signal(None::);
- let (error, set_error) = create_signal(None::);
+ let (error, set_error) = create_signal(None::>);
- let post = move |data: T| {
- if let Some(channel) = channel.get_untracked() {
- channel.post_message().ok();
+ let codec = C::default();
+
+ let post = {
+ let codec = codec.clone();
+
+ move |data: &T| {
+ if let Some(channel) = channel.get_untracked() {
+ match codec.encode(data) {
+ Ok(msg) => {
+ channel
+ .post_message(&msg.into())
+ .map_err(|err| {
+ set_error.set(Some(UseBroadcastChannelError::PostMessage(err)))
+ })
+ .ok();
+ }
+ Err(err) => {
+ set_error.set(Some(UseBroadcastChannelError::Encode(err)));
+ }
+ }
+ }
}
};
+
+ let close = {
+ let channel = channel.clone();
+
+ move || {
+ if let Some(channel) = channel.get_untracked() {
+ channel.close();
+ }
+ set_closed.set(true);
+ }
+ };
+
+ if is_supported.get_untracked() {
+ let channel_val = web_sys::BroadcastChannel::new(name).ok();
+ set_channel.set(channel_val.clone());
+
+ if let Some(channel) = channel_val {
+ let _ = use_event_listener_with_options(
+ channel.clone(),
+ ev::message,
+ move |event| {
+ if let Some(data) = event.data().as_string() {
+ match codec.decode(data) {
+ Ok(msg) => {
+ set_message.set(Some(msg));
+ }
+ Err(err) => set_error.set(Some(UseBroadcastChannelError::Decode(err))),
+ }
+ } else {
+ set_error.set(Some(UseBroadcastChannelError::ValueNotString));
+ }
+ },
+ UseEventListenerOptions::default().passive(true),
+ );
+
+ let _ = use_event_listener_with_options(
+ channel.clone(),
+ ev::messageerror,
+ move |event| {
+ set_error.set(Some(UseBroadcastChannelError::MessageEvent(event)));
+ },
+ UseEventListenerOptions::default().passive(true),
+ );
+
+ let _ = use_event_listener(channel, ev::close, move |_| set_closed.set(true));
+ }
+ }
+
+ on_cleanup(move || {
+ close();
+ });
+
+ return UseBroadcastChannelReturn {
+ is_supported,
+ channel: channel.into(),
+ message: message.into(),
+ post,
+ close,
+ error: error.into(),
+ is_closed: is_closed.into(),
+ };
}
/// Return type of [`use_broadcast_channel`].
-pub struct UseBroadcastChannelReturn
+pub struct UseBroadcastChannelReturn
where
- PFn: Fn(T),
- CFn: Fn(),
+ T: 'static,
+ PFn: Fn(&T) + Clone,
+ CFn: Fn() + Clone,
+ Err: 'static,
{
/// `true` if this browser supports `BroadcastChannel`s.
- is_supported: Signal,
+ pub is_supported: Signal,
/// The broadcast channel that is wrapped by this function
- channel: Signal