mirror of
https://github.com/leptos-rs/leptos.git
synced 2025-12-28 10:11:56 -05:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b484b39779 | ||
|
|
a0d657f9b1 | ||
|
|
cddb24ebd3 | ||
|
|
e8afd11995 | ||
|
|
4d01d95175 | ||
|
|
9bf5b22633 | ||
|
|
da4a7d5285 | ||
|
|
2af6c6353c |
@@ -440,7 +440,14 @@ pub fn FileUploadWithProgress() -> impl IntoView {
|
||||
let mut entry =
|
||||
FILES.entry(filename.to_string()).or_insert_with(|| {
|
||||
println!("[{filename}]\tinserting channel");
|
||||
let (tx, rx) = broadcast(128);
|
||||
// NOTE: this channel capacity is set arbitrarily for this demo code.
|
||||
// it allows for up to exactly 1048 chunks to be sent, which sets an upper cap
|
||||
// on upload size (the precise details vary by client)
|
||||
// in a real system, you will want to create some more reasonable ways of
|
||||
// sending and sharing notifications
|
||||
//
|
||||
// see https://github.com/leptos-rs/leptos/issues/4397 for related discussion
|
||||
let (tx, rx) = broadcast(1048);
|
||||
File { total: 0, tx, rx }
|
||||
});
|
||||
entry.total += len;
|
||||
|
||||
@@ -121,7 +121,7 @@ pub trait ExtendResponse: Sized {
|
||||
// drop the owner, cleaning up the reactive runtime,
|
||||
// once the stream is over
|
||||
.chain(once(async move {
|
||||
owner.unset();
|
||||
owner.unset_with_forced_cleanup();
|
||||
Default::default()
|
||||
})),
|
||||
));
|
||||
|
||||
@@ -4,6 +4,7 @@ version = "0.8.12"
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/leptos-rs/leptos"
|
||||
homepage = "https://leptos.dev/"
|
||||
description = "Leptos is a full-stack, isomorphic Rust web framework leveraging fine-grained reactivity to build declarative user interfaces."
|
||||
readme = "../README.md"
|
||||
rust-version.workspace = true
|
||||
|
||||
@@ -221,18 +221,15 @@ fn env_w_default(
|
||||
/// An enum that can be used to define the environment Leptos is running in.
|
||||
/// Setting this to the `PROD` variant will not include the WebSocket code for `cargo-leptos` watch mode.
|
||||
/// Defaults to `DEV`.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Default,
|
||||
)]
|
||||
pub enum Env {
|
||||
PROD,
|
||||
#[default]
|
||||
DEV,
|
||||
}
|
||||
|
||||
impl Default for Env {
|
||||
fn default() -> Self {
|
||||
Self::DEV
|
||||
}
|
||||
}
|
||||
|
||||
fn env_from_str(input: &str) -> Result<Env, LeptosConfigError> {
|
||||
let sanitized = input.to_lowercase();
|
||||
match sanitized.as_ref() {
|
||||
@@ -279,18 +276,15 @@ impl TryFrom<String> for Env {
|
||||
|
||||
/// An enum that can be used to define the websocket protocol Leptos uses for hotreloading
|
||||
/// Defaults to `ws`.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
|
||||
#[derive(
|
||||
Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Default,
|
||||
)]
|
||||
pub enum ReloadWSProtocol {
|
||||
#[default]
|
||||
WS,
|
||||
WSS,
|
||||
}
|
||||
|
||||
impl Default for ReloadWSProtocol {
|
||||
fn default() -> Self {
|
||||
Self::WS
|
||||
}
|
||||
}
|
||||
|
||||
fn ws_from_str(input: &str) -> Result<ReloadWSProtocol, LeptosConfigError> {
|
||||
let sanitized = input.to_lowercase();
|
||||
match sanitized.as_ref() {
|
||||
|
||||
@@ -340,6 +340,8 @@ impl Owner {
|
||||
}
|
||||
|
||||
/// Removes this from its state as the thread-local owner and drops it.
|
||||
/// If there are other holders of this owner, it may not cleanup, if always cleaning up is required,
|
||||
/// see [`Owner::unset_with_forced_cleanup`].
|
||||
pub fn unset(self) {
|
||||
OWNER.with_borrow_mut(|owner| {
|
||||
if owner.as_ref().and_then(|n| n.upgrade()) == Some(self) {
|
||||
@@ -348,6 +350,23 @@ impl Owner {
|
||||
})
|
||||
}
|
||||
|
||||
/// Removes this from its state as the thread-local owner and drops it.
|
||||
/// Unlike [`Owner::unset`], this will always run cleanup on this owner,
|
||||
/// even if there are other holders of this owner.
|
||||
pub fn unset_with_forced_cleanup(self) {
|
||||
OWNER.with_borrow_mut(|owner| {
|
||||
if owner
|
||||
.as_ref()
|
||||
.and_then(|n| n.upgrade())
|
||||
.map(|o| o == self)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
mem::take(owner);
|
||||
}
|
||||
});
|
||||
self.cleanup();
|
||||
}
|
||||
|
||||
/// Returns the current [`SharedContext`], if any.
|
||||
#[cfg(feature = "hydration")]
|
||||
pub fn current_shared_context(
|
||||
|
||||
@@ -368,8 +368,8 @@ where
|
||||
ev.prevent_default();
|
||||
let to = path_name
|
||||
+ if url.search.is_empty() { "" } else { "?" }
|
||||
+ &Url::unescape(&url.search)
|
||||
+ &Url::unescape(&url.hash);
|
||||
+ &url.search
|
||||
+ &url.hash;
|
||||
let state = Reflect::get(&a, &JsValue::from_str("state"))
|
||||
.ok()
|
||||
.and_then(|value| {
|
||||
|
||||
@@ -4,7 +4,6 @@ macro_rules! tuples {
|
||||
($first:ident => $($ty:ident),*) => {
|
||||
impl<$first, $($ty),*> PossibleRouteMatch for ($first, $($ty,)*)
|
||||
where
|
||||
Self: core::fmt::Debug,
|
||||
$first: PossibleRouteMatch,
|
||||
$($ty: PossibleRouteMatch),*,
|
||||
{
|
||||
|
||||
@@ -369,7 +369,7 @@ impl ResolvedStaticPath {
|
||||
eprintln!("{e}");
|
||||
}
|
||||
}
|
||||
owner.unset();
|
||||
owner.unset_with_forced_cleanup();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -317,6 +317,26 @@ where
|
||||
type State = ElementState<At::State, Ch::State>;
|
||||
|
||||
fn rebuild(self, state: &mut Self::State) {
|
||||
// check whether the tag is the same, for custom elements
|
||||
// because this is const `false` for all other element types,
|
||||
// the compiler should be able to optimize it out
|
||||
if E::TAG.is_empty() {
|
||||
// see https://github.com/leptos-rs/leptos/issues/4412
|
||||
let new_tag = self.tag.tag();
|
||||
|
||||
// this is not particularly efficient, but it saves us from
|
||||
// having to keep track of the tag name for every element state
|
||||
let old_tag = state.el.tag_name();
|
||||
if new_tag != old_tag {
|
||||
let mut new_state = self.build();
|
||||
state.insert_before_this(&mut new_state);
|
||||
state.unmount();
|
||||
*state = new_state;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild attributes and children for any element
|
||||
let ElementState {
|
||||
attrs, children, ..
|
||||
} = state;
|
||||
|
||||
@@ -642,18 +642,13 @@ struct DiffOpRemove {
|
||||
at: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
enum DiffOpAddMode {
|
||||
#[default]
|
||||
Normal,
|
||||
Append,
|
||||
}
|
||||
|
||||
impl Default for DiffOpAddMode {
|
||||
fn default() -> Self {
|
||||
Self::Normal
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_diff<T, VFS, V>(
|
||||
parent: Option<&crate::renderer::types::Element>,
|
||||
marker: &crate::renderer::types::Placeholder,
|
||||
|
||||
Reference in New Issue
Block a user