added use_broadcast_channel

This commit is contained in:
Maccesch 2024-01-29 21:29:39 +00:00
parent 0d546d464a
commit 7fe153e525
21 changed files with 282 additions and 78 deletions

5
.idea/leptos-use.iml generated
View file

@ -63,6 +63,11 @@
<sourceFolder url="file://$MODULE_DIR$/examples/use_web_notification/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/client/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/server/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_broadcast_channel/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_cookie/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_device_pixel_ratio/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_element_bounding/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_mouse_in_element/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/examples/use_event_listener/target" />
<excludeFolder url="file://$MODULE_DIR$/target" />
<excludeFolder url="file://$MODULE_DIR$/docs/book/book" />

View file

@ -61,7 +61,7 @@
# Network
- [use_websocket](network/use_websocket.md)
- [use_webtransport](network/use_webtransport.md)
<!-- - [use_webtransport](network/use_webtransport.md) -->
# Animation

View file

@ -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"

View file

@ -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::<String, FromToStringCodec>("leptos-use-demo-channel");
use_broadcast_channel();
let (input_value, set_input_value) = create_signal(String::new());
view! { }
view! {
<p>Please open this page in at least two tabs</p>
<Show
when=move || is_supported()
fallback=move || view! { <p>"BroadcastChannel not supported"</p> }
>
<form on:submit={
let post = post.clone();
move |ev: web_sys::SubmitEvent| {
ev.prevent_default();
let value = input_value();
post(&value);
}
}>
<input
value=input_value
on:input=move |event| {
set_input_value(event_target_value(&event));
}
type="text"
/>
<button type="submit">Send Message</button>
</form>
<Show when=move || message().is_some()>
<p>"Received message: " {move || message().as_ref().unwrap().to_string()}</p>
</Show>
<Show when=move || error().is_some()>
<p>"Error: " {move || format!("{:?}", error().as_ref().unwrap())}</p>
</Show>
</Show>
}
}
fn main() {

View file

@ -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"

View file

@ -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"

View file

@ -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::*;

View file

@ -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::*;

View file

@ -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<T, C>(
) -> (Signal<T>, WriteSignal<T>, impl Fn() + Clone)
where
T: Clone + Default + PartialEq,
C: Codec<T> + Default,
C: StringCodec<T> + Default,
{
use_storage_with_options(
StorageType::Local,
@ -30,7 +31,7 @@ pub fn use_local_storage_with_options<T, C>(
) -> (Signal<T>, WriteSignal<T>, impl Fn() + Clone)
where
T: Clone + PartialEq,
C: Codec<T>,
C: StringCodec<T>,
{
use_storage_with_options(StorageType::Local, key, options)
}

View file

@ -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<T, C>(
) -> (Signal<T>, WriteSignal<T>, impl Fn() + Clone)
where
T: Clone + Default + PartialEq,
C: Codec<T> + Default,
C: StringCodec<T> + Default,
{
use_storage_with_options(
StorageType::Session,
@ -30,7 +31,7 @@ pub fn use_session_storage_with_options<T, C>(
) -> (Signal<T>, WriteSignal<T>, impl Fn() + Clone)
where
T: Clone + PartialEq,
C: Codec<T>,
C: StringCodec<T>,
{
use_storage_with_options(StorageType::Session, key, options)
}

View file

@ -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::<MyState, JsonCodec>("my-state");
///
/// // Binds a bool, stored as a string:
/// let (flag, set_flag, remove_flag) = use_session_storage::<bool, StringCodec>("my-flag");
/// let (flag, set_flag, remove_flag) = use_session_storage::<bool, FromToStringCodec>("my-flag");
///
/// // Binds a number, stored as a string:
/// let (count, set_count, _) = use_session_storage::<i32, StringCodec>("my-count");
/// let (count, set_count, _) = use_session_storage::<i32, FromToStringCodec>("my-count");
/// // Binds a number, stored in JSON:
/// let (count, set_count, _) = use_session_storage::<i32, JsonCodec>("my-count-kept-in-js");
///
@ -89,7 +91,11 @@ pub fn use_storage(
storage_type: StorageType,
key: impl AsRef<str>,
) -> (Signal<String>, WriteSignal<String>, impl Fn() + Clone) {
use_storage_with_options::<String, StringCodec>(storage_type, key, UseStorageOptions::default())
use_storage_with_options::<String, FromToStringCodec>(
storage_type,
key,
UseStorageOptions::default(),
)
}
/// Version of [`use_storage`] that accepts [`UseStorageOptions`].
@ -100,7 +106,7 @@ pub fn use_storage_with_options<T, C>(
) -> (Signal<T>, WriteSignal<T>, impl Fn() + Clone)
where
T: Clone + PartialEq,
C: Codec<T>,
C: StringCodec<T>,
{
let UseStorageOptions {
codec,
@ -322,7 +328,7 @@ pub enum UseStorageError<Err> {
}
/// Options for use with [`use_local_storage_with_options`], [`use_session_storage_with_options`] and [`use_storage_with_options`].
pub struct UseStorageOptions<T: 'static, C: Codec<T>> {
pub struct UseStorageOptions<T: 'static, C: StringCodec<T>> {
// Translates to and from UTF-16 strings
codec: C,
// Callback for when an error occurs
@ -344,7 +350,7 @@ fn handle_error<T, Err>(
result.map_err(|err| (on_error)(err))
}
impl<T: Default, C: Codec<T> + Default> Default for UseStorageOptions<T, C> {
impl<T: Default, C: StringCodec<T> + Default> Default for UseStorageOptions<T, C> {
fn default() -> Self {
Self {
codec: C::default(),
@ -356,7 +362,7 @@ impl<T: Default, C: Codec<T> + Default> Default for UseStorageOptions<T, C> {
}
}
impl<T: Default, C: Codec<T>> UseStorageOptions<T, C> {
impl<T: Default, C: StringCodec<T>> UseStorageOptions<T, C> {
/// Sets the codec to use for encoding and decoding values to and from UTF-16 strings.
pub fn codec(self, codec: impl Into<C>) -> Self {
Self {

View file

@ -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::<bool, FromToStringCodec>("some-channel-name");
///
/// post(&true);
///
/// close();
/// #
/// # view! { }
/// # }
/// ```
pub fn use_broadcast_channel<T, C>(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::<MyState, JsonCodec>("everyting-is-awesome");
/// # view! { }
/// # }
/// ```
pub fn use_broadcast_channel<T, C>(
name: &str,
) -> UseBroadcastChannelReturn<T, impl Fn(&T) + Clone, impl Fn() + Clone, C::Error>
where
C: Codec<T> + Default + Clone,
C: StringCodec<T> + 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::<web_sys::BroadcastChannel>);
let (message, set_message) = create_signal(None::<T>);
let (error, set_error) = create_signal(None::<web_sys::MessageEvent>);
let (error, set_error) = create_signal(None::<UseBroadcastChannelError<C::Error>>);
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<T, PFn, CFn>
pub struct UseBroadcastChannelReturn<T, PFn, CFn, Err>
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<bool>,
pub is_supported: Signal<bool>,
/// The broadcast channel that is wrapped by this function
channel: Signal<Option<web_sys::BroadcastChannel>>,
pub channel: Signal<Option<web_sys::BroadcastChannel>>,
/// Latest message received from the channel
message: Signal<Option<T>>,
pub message: Signal<Option<T>>,
/// Sends a message through the channel
post: PFn,
pub post: PFn,
/// Closes the channel
close: CFn,
pub close: CFn,
/// Latest error as reported by the `messageerror` event.
error: Signal<Option<web_sys::MessageEvent>>,
pub error: Signal<Option<UseBroadcastChannelError<Err>>>,
/// Wether the channel is closed
is_closed: Signal<bool>,
pub is_closed: Signal<bool>,
}
#[derive(Debug, Error, Clone)]
pub enum UseBroadcastChannelError<Err> {
#[error("failed to post message")]
PostMessage(JsValue),
#[error("channel message error")]
MessageEvent(web_sys::MessageEvent),
#[error("failed to encode value")]
Encode(Err),
#[error("failed to decode value")]
Decode(Err),
#[error("received value is not a string")]
ValueNotString,
}

View file

@ -1,14 +1,14 @@
use crate::core::{ElementMaybeSignal, MaybeRwSignal};
use crate::storage::{use_storage_with_options, StringCodec, UseStorageOptions};
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use crate::core::StorageType;
use crate::core::{ElementMaybeSignal, MaybeRwSignal};
use crate::storage::{use_storage_with_options, UseStorageOptions};
use crate::use_preferred_dark;
use crate::utils::FromToStringCodec;
use default_struct_builder::DefaultBuilder;
use leptos::*;
use std::fmt::{Display, Formatter};
use std::marker::PhantomData;
use std::rc::Rc;
use std::str::FromStr;
use wasm_bindgen::JsCast;
/// Reactive color mode (dark / light / customs) with auto data persistence.
@ -261,7 +261,7 @@ fn get_store_signal(
let (store, set_store) = storage_signal.split();
(store.into(), set_store)
} else if storage_enabled {
let (store, set_store, _) = use_storage_with_options::<ColorMode, StringCodec>(
let (store, set_store, _) = use_storage_with_options::<ColorMode, FromToStringCodec>(
storage,
storage_key,
UseStorageOptions::default()

View file

@ -1,6 +1,5 @@
use cookie::Cookie;
use default_struct_builder::DefaultBuilder;
use std::rc::Rc;
/// Get a cookie by name, for both SSR and CSR
///
@ -75,7 +74,7 @@ pub fn use_cookie_with_options(
ssr_cookies_header_getter,
} = options;
let cookie = read_cookies_string(ssr_cookies_header_getter);
let cookies = read_cookies_string(ssr_cookies_header_getter);
Cookie::split_parse_encoded(cookies)
.filter_map(|cookie| cookie.ok())
@ -84,7 +83,7 @@ pub fn use_cookie_with_options(
}
/// Options for [`use_cookie_with_options`].
#[derive(Clone, DefaultBuilder)]
#[derive(DefaultBuilder)]
pub struct UseCookieOptions {
/// Getter function to return the string value of the cookie header.
/// When you use one of the features "axum" or "actix" there's a valid default implementation provided.
@ -148,15 +147,23 @@ impl Default for UseCookieOptions {
}
fn read_cookies_string(ssr_cookies_header_getter: Box<dyn Fn() -> String>) -> String {
let cookies;
#[cfg(feature = "ssr")]
ssr_cookies_header_getter();
{
cookies = ssr_cookies_header_getter();
}
#[cfg(not(feature = "ssr"))]
{
use wasm_bindgen::JsCast;
let _ = ssr_cookies_header_getter;
let js_value: wasm_bindgen::JsValue = leptos::document().into();
let document: web_sys::HtmlDocument = js_value.unchecked_into();
document.cookie().unwrap_or_default()
cookies = document.cookie().unwrap_or_default();
}
cookies
}

View file

@ -18,9 +18,9 @@ use web_sys::PointerEvent;
///
/// ```
/// # use leptos::*;
/// use leptos::html::Div;
/// # use leptos::html::Div;
/// # use leptos_use::{use_draggable_with_options, UseDraggableOptions, UseDraggableReturn};
/// use leptos_use::core::Position;
/// # use leptos_use::core::Position;
/// #
/// # #[component]
/// # fn Demo() -> impl IntoView {

View file

@ -1,9 +1,10 @@
use super::BinCodec;
use thiserror::Error;
#[derive(Copy, Clone, Default, PartialEq)]
pub struct FromToBytesCodec;
#[derive(Error, Debug, PartialEq)]
#[derive(Error, Debug)]
pub enum FromToBytesCodecError {
#[error("failed to convert byte slice to byte array")]
InvalidByteSlice(#[from] std::array::TryFromSliceError),

View file

@ -1,5 +1,6 @@
mod from_to_bytes;
#[allow(unused_imports)]
pub use from_to_bytes::*;
/// A codec for encoding and decoding values to and from strings.

View file

@ -8,10 +8,11 @@ use std::str::FromStr;
/// ## Example
/// ```
/// # use leptos::*;
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions, StringCodec};
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions};
/// # use leptos_use::utils::FromToStringCodec;
/// #
/// # pub fn Demo() -> impl IntoView {
/// let (get, set, remove) = use_local_storage::<i32, StringCodec>("my-key");
/// let (get, set, remove) = use_local_storage::<i32, FromToStringCodec>("my-key");
/// # view! { }
/// # }
/// ```

View file

@ -5,8 +5,9 @@ use super::StringCodec;
/// ## Example
/// ```
/// # use leptos::*;
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions, JsonCodec};
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions};
/// # use serde::{Deserialize, Serialize};
/// # use leptos_use::utils::JsonCodec;
/// #
/// # pub fn Demo() -> impl IntoView {
/// // Primitive types:
@ -34,8 +35,9 @@ use super::StringCodec;
///
/// ```
/// # use leptos::*;
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions, Codec, JsonCodec};
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions};
/// # use serde::{Deserialize, Serialize};
/// # use leptos_use::utils::StringCodec;
/// #
/// # pub fn Demo() -> impl IntoView {
/// #[derive(Serialize, Deserialize, Clone, Default, PartialEq)]
@ -46,7 +48,7 @@ use super::StringCodec;
///
/// #[derive(Clone, Default)]
/// pub struct MyStateCodec();
/// impl Codec<MyState> for MyStateCodec {
/// impl StringCodec<MyState> for MyStateCodec {
/// type Error = serde_json::Error;
///
/// fn encode(&self, val: &MyState) -> Result<String, Self::Error> {
@ -75,9 +77,10 @@ use super::StringCodec;
///
/// ```
/// # use leptos::*;
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions, Codec, JsonCodec};
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions};
/// # use serde::{Deserialize, Serialize};
/// # use serde_json::json;
/// # use leptos_use::utils::StringCodec;
/// #
/// # pub fn Demo() -> impl IntoView {
/// #[derive(Serialize, Deserialize, Clone, Default, PartialEq)]
@ -88,7 +91,7 @@ use super::StringCodec;
///
/// #[derive(Clone, Default)]
/// pub struct MyStateCodec();
/// impl Codec<MyState> for MyStateCodec {
/// impl StringCodec<MyState> for MyStateCodec {
/// type Error = serde_json::Error;
///
/// fn encode(&self, val: &MyState) -> Result<String, Self::Error> {

View file

@ -11,7 +11,8 @@ use thiserror::Error;
/// ## Example
/// ```
/// # use leptos::*;
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions, ProstCodec};
/// # use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions};
/// # use leptos_use::utils::ProstCodec;
/// #
/// # pub fn Demo() -> impl IntoView {
/// // Primitive types:

View file

@ -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"