Compare commits

...

4 Commits

Author SHA1 Message Date
autofix-ci[bot]
0dc6b7b56b [autofix.ci] apply automated fixes (attempt 2/3) 2026-01-02 21:30:57 +00:00
autofix-ci[bot]
3a2700ac56 [autofix.ci] apply automated fixes 2026-01-02 20:24:10 +00:00
Greg Johnston
421ed40e9d chore: remove conditional code for wasm32 from stores 2026-01-02 14:46:16 -05:00
Greg Johnston
588f6db557 chore: remove dashmap (cf. #4408) 2026-01-02 14:45:59 -05:00
12 changed files with 95 additions and 132 deletions

27
Cargo.lock generated
View File

@@ -845,20 +845,6 @@ dependencies = [
"typenum",
]
[[package]]
name = "dashmap"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
dependencies = [
"cfg-if",
"crossbeam-utils",
"hashbrown 0.14.5",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]]
name = "data-encoding"
version = "2.9.0"
@@ -1465,12 +1451,6 @@ dependencies = [
"byteorder",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.5"
@@ -1947,7 +1927,6 @@ dependencies = [
"actix-http",
"actix-web",
"any_spawner",
"dashmap",
"futures",
"hydration_context",
"leptos",
@@ -1955,6 +1934,7 @@ dependencies = [
"leptos_macro",
"leptos_meta",
"leptos_router",
"or_poisoned",
"parking_lot",
"send_wrapper",
"serde_json",
@@ -1970,7 +1950,6 @@ version = "0.8.7"
dependencies = [
"any_spawner",
"axum",
"dashmap",
"futures",
"hydration_context",
"leptos",
@@ -1978,6 +1957,7 @@ dependencies = [
"leptos_macro",
"leptos_meta",
"leptos_router",
"or_poisoned",
"parking_lot",
"server_fn",
"tachys",
@@ -2920,7 +2900,6 @@ name = "reactive_stores"
version = "0.3.1"
dependencies = [
"any_spawner",
"dashmap",
"guardian",
"itertools",
"leptos",
@@ -3435,7 +3414,6 @@ dependencies = [
"ciborium",
"const-str",
"const_format",
"dashmap",
"futures",
"gloo-net",
"http 1.4.0",
@@ -3444,6 +3422,7 @@ dependencies = [
"inventory",
"js-sys",
"multer",
"or_poisoned",
"pin-project-lite",
"postcard",
"reqwest",

View File

@@ -89,7 +89,6 @@ actix-web = { default-features = false, version = "4.12.1" }
tracing = { default-features = false, version = "0.1.44" }
slotmap = { default-features = false, version = "1.1.1" }
futures = { default-features = false, version = "0.3.31" }
dashmap = { default-features = false, version = "6.1.0" }
pin-project-lite = { default-features = false, version = "0.2.16" }
send_wrapper = { default-features = false, version = "0.6.0" }
tokio-test = { default-features = false, version = "0.4.4" }

View File

@@ -37,7 +37,6 @@ web-sys = { version = "0.3.70", features = ["FileList", "File"] }
strum = { version = "0.27.1", features = ["strum_macros", "derive"] }
notify = { version = "8.0", optional = true }
pin-project-lite = "0.2.14"
dashmap = { version = "6.0", optional = true }
async-broadcast = { version = "0.7.1", optional = true }
bytecheck = "0.8.0"
rkyv = { version = "0.8.8" }
@@ -52,7 +51,6 @@ ssr = [
"leptos/ssr",
"dep:leptos_axum",
"dep:notify",
"dep:dashmap",
"dep:async-broadcast",
]

View File

@@ -422,7 +422,6 @@ pub fn FileUploadWithProgress() -> impl IntoView {
#[cfg(feature = "ssr")]
mod progress {
use async_broadcast::{broadcast, Receiver, Sender};
use dashmap::DashMap;
use futures::Stream;
use std::sync::LazyLock;

View File

@@ -27,7 +27,7 @@ parking_lot = { workspace = true, default-features = true }
tracing = { optional = true, workspace = true, default-features = true }
tokio = { features = ["rt", "fs"], workspace = true, default-features = true }
send_wrapper = { workspace = true, default-features = true }
dashmap = { workspace = true, default-features = true }
or_poisoned = { workspace = true, default-features = true }
[package.metadata.docs.rs]
rustdoc-args = ["--generate-link-to-definition"]

View File

@@ -16,7 +16,6 @@ use actix_web::{
web::{Data, Payload, ServiceConfig},
*,
};
use dashmap::DashMap;
use futures::{stream::once, Stream, StreamExt};
use http::StatusCode;
use hydration_context::SsrSharedContext;
@@ -38,6 +37,7 @@ use leptos_router::{
static_routes::{RegenerationFn, ResolvedStaticPath},
ExpandOptionals, Method, PathSegment, RouteList, RouteListing, SsrMode,
};
use or_poisoned::OrPoisoned;
use parking_lot::RwLock;
use send_wrapper::SendWrapper;
use server_fn::{
@@ -45,7 +45,7 @@ use server_fn::{
request::actix::ActixRequest,
};
use std::{
collections::HashSet,
collections::{HashMap, HashSet},
fmt::{Debug, Display},
future::Future,
ops::{Deref, DerefMut},
@@ -1222,8 +1222,9 @@ impl StaticRouteGenerator {
}
}
static STATIC_HEADERS: LazyLock<DashMap<String, ResponseOptions>> =
LazyLock::new(DashMap::new);
static STATIC_HEADERS: LazyLock<
std::sync::RwLock<HashMap<String, ResponseOptions>>,
> = LazyLock::new(Default::default);
fn was_404(owner: &Owner) -> bool {
let resp = owner.with(|| expect_context::<ResponseOptions>());
@@ -1255,7 +1256,10 @@ async fn write_static_route(
html: &str,
) -> Result<(), std::io::Error> {
if let Some(options) = response_options {
STATIC_HEADERS.insert(path.to_string(), options);
STATIC_HEADERS
.write()
.or_poisoned()
.insert(path.to_string(), options);
}
let path = static_path(options, path);
@@ -1322,8 +1326,11 @@ where
.await;
(owner.with(use_context::<ResponseOptions>), html)
} else {
let headers =
STATIC_HEADERS.get(orig_path).map(|v| v.clone());
let headers = STATIC_HEADERS
.read()
.or_poisoned()
.get(orig_path)
.cloned();
(headers, None)
};

View File

@@ -14,7 +14,6 @@ hydration_context = { workspace = true }
axum = { default-features = false, features = [
"matched-path",
], workspace = true }
dashmap = { workspace = true, default-features = true }
futures = { workspace = true, default-features = true }
leptos = { workspace = true, features = ["nonce", "ssr"] }
server_fn = { workspace = true, features = ["axum-no-default"] }
@@ -28,6 +27,7 @@ tokio = { default-features = false, workspace = true }
tower = { features = ["util"], workspace = true, default-features = true }
tower-http = { workspace = true, default-features = true }
tracing = { optional = true, workspace = true, default-features = true }
or_poisoned = { workspace = true, default-features = true }
[dev-dependencies]
axum = { workspace = true, default-features = true }

View File

@@ -47,8 +47,6 @@ use axum::{
response::IntoResponse,
routing::{delete, get, patch, post, put},
};
#[cfg(feature = "default")]
use dashmap::DashMap;
use futures::{stream::once, Future, Stream, StreamExt};
use hydration_context::SsrSharedContext;
use leptos::{
@@ -69,12 +67,13 @@ use leptos_router::{
static_routes::RegenerationFn, ExpandOptionals, PathSegment, RouteList,
RouteListing, SsrMode,
};
use or_poisoned::OrPoisoned;
use parking_lot::RwLock;
use server_fn::{error::ServerFnErrorErr, redirect::REDIRECT_HEADER};
#[cfg(feature = "default")]
use std::path::Path;
#[cfg(feature = "default")]
use std::sync::LazyLock;
#[cfg(feature = "default")]
use std::{collections::HashMap, path::Path};
use std::{collections::HashSet, fmt::Debug, io, pin::Pin, sync::Arc};
#[cfg(feature = "default")]
use tower::util::ServiceExt;
@@ -1522,8 +1521,9 @@ impl StaticRouteGenerator {
}
#[cfg(feature = "default")]
static STATIC_HEADERS: LazyLock<DashMap<String, ResponseOptions>> =
LazyLock::new(DashMap::new);
static STATIC_HEADERS: LazyLock<
std::sync::RwLock<HashMap<String, ResponseOptions>>,
> = LazyLock::new(Default::default);
#[cfg(feature = "default")]
fn was_404(owner: &Owner) -> bool {
@@ -1558,7 +1558,10 @@ async fn write_static_route(
html: &str,
) -> Result<(), std::io::Error> {
if let Some(options) = response_options {
STATIC_HEADERS.insert(path.to_string(), options);
STATIC_HEADERS
.write()
.or_poisoned()
.insert(path.to_string(), options);
}
let path = static_path(options, path);
@@ -1635,7 +1638,11 @@ where
.await;
(owner.with(use_context::<ResponseOptions>), html)
} else {
let headers = STATIC_HEADERS.get(orig_path).map(|v| v.clone());
let headers = STATIC_HEADERS
.read()
.or_poisoned()
.get(orig_path)
.map(|v| v.clone());
(headers, None)
};

View File

@@ -17,7 +17,6 @@ paste = { workspace = true, default-features = true }
reactive_graph = { workspace = true }
rustc-hash = { workspace = true, default-features = true }
reactive_stores_macro = { workspace = true }
dashmap = { workspace = true, default-features = true }
send_wrapper = { workspace = true, default-features = true }
[dev-dependencies]

View File

@@ -239,6 +239,7 @@
//! field in the signal inner `Arc<RwLock<_>>`, and tracks the trigger that corresponds with its
//! path; calling `.write()` returns a writeable guard, and notifies that same trigger.
use or_poisoned::OrPoisoned;
use reactive_graph::{
owner::{ArenaItem, LocalStorage, Storage, SyncStorage},
signal::{
@@ -414,32 +415,15 @@ impl<K> Default for FieldKeys<K> {
}
}
#[cfg(not(target_arch = "wasm32"))]
type HashMap<K, V> = Arc<dashmap::DashMap<K, V>>;
#[cfg(target_arch = "wasm32")]
type HashMap<K, V> = send_wrapper::SendWrapper<
std::rc::Rc<std::cell::RefCell<std::collections::HashMap<K, V>>>,
>;
type Map<K, V> = Arc<std::sync::RwLock<std::collections::HashMap<K, V>>>;
/// A map of the keys for a keyed subfield.
#[derive(Clone)]
#[derive(Clone, Default)]
pub struct KeyMap(
HashMap<StorePath, Box<dyn Any + Send + Sync>>,
HashMap<(StorePath, usize), StorePathSegment>,
Map<StorePath, Box<dyn Any + Send + Sync>>,
Map<(StorePath, usize), StorePathSegment>,
);
impl Default for KeyMap {
fn default() -> Self {
#[cfg(not(target_arch = "wasm32"))]
return Self(Default::default(), Default::default());
#[cfg(target_arch = "wasm32")]
return Self(
send_wrapper::SendWrapper::new(Default::default()),
send_wrapper::SendWrapper::new(Default::default()),
);
}
}
impl KeyMap {
fn with_field_keys<K, T>(
&self,
@@ -452,62 +436,33 @@ impl KeyMap {
{
let initial_keys = initialize();
#[cfg(not(target_arch = "wasm32"))]
let mut entry = self
.0
let mut guard = self.0.write().or_poisoned();
let entry = guard
.entry(path.clone())
.or_insert_with(|| Box::new(FieldKeys::new(initial_keys)));
#[cfg(target_arch = "wasm32")]
let entry = if !self.0.borrow().contains_key(&path) {
Some(Box::new(FieldKeys::new(initial_keys)))
} else {
None
};
#[cfg(target_arch = "wasm32")]
let mut map = self.0.borrow_mut();
#[cfg(target_arch = "wasm32")]
let entry = map.entry(path.clone()).or_insert_with(|| entry.unwrap());
let entry = entry.downcast_mut::<FieldKeys<K>>()?;
let (result, new_keys) = fun(entry);
if !new_keys.is_empty() {
for (idx, segment) in new_keys {
#[cfg(not(target_arch = "wasm32"))]
self.1.insert((path.clone(), idx), segment);
#[cfg(target_arch = "wasm32")]
self.1.borrow_mut().insert((path.clone(), idx), segment);
self.1
.write()
.or_poisoned()
.insert((path.clone(), idx), segment);
}
}
Some(result)
}
fn contains_key(&self, key: &StorePath) -> bool {
#[cfg(not(target_arch = "wasm32"))]
{
self.0.contains_key(key)
}
#[cfg(target_arch = "wasm32")]
{
self.0.borrow_mut().contains_key(key)
}
self.0.read().or_poisoned().contains_key(key)
}
fn get_key_for_index(
&self,
key: &(StorePath, usize),
) -> Option<StorePathSegment> {
#[cfg(not(target_arch = "wasm32"))]
{
self.1.get(key).as_deref().copied()
}
#[cfg(target_arch = "wasm32")]
{
self.1.borrow().get(key).as_deref().copied()
}
self.1.read().or_poisoned().get(key).copied()
}
}

View File

@@ -25,10 +25,10 @@ send_wrapper = { features = [
"futures",
], optional = true, workspace = true, default-features = true }
thiserror = { workspace = true, default-features = true }
or_poisoned = { workspace = true, default-features = true }
# registration system
inventory = { optional = true, workspace = true, default-features = true }
dashmap = { workspace = true, default-features = true }
## servers
# actix

View File

@@ -145,7 +145,6 @@ use codec::{Encoding, FromReq, FromRes, IntoReq, IntoRes};
pub use const_format;
#[doc(hidden)]
pub use const_str;
use dashmap::DashMap;
pub use error::ServerFnError;
#[cfg(feature = "form-redirects")]
use error::ServerFnUrlError;
@@ -165,12 +164,13 @@ pub use serde;
pub use serde_lite;
use server::Server;
use std::{
collections::HashMap,
fmt::{Debug, Display},
future::Future,
marker::PhantomData,
ops::{Deref, DerefMut},
pin::Pin,
sync::{Arc, LazyLock},
sync::{Arc, LazyLock, RwLock},
};
#[doc(hidden)]
pub use xxhash_rust;
@@ -866,12 +866,14 @@ pub use inventory;
macro_rules! initialize_server_fn_map {
($req:ty, $res:ty) => {
std::sync::LazyLock::new(|| {
$crate::inventory::iter::<ServerFnTraitObj<$req, $res>>
.into_iter()
.map(|obj| {
((obj.path().to_string(), obj.method()), obj.clone())
})
.collect()
std::sync::RwLock::new(
$crate::inventory::iter::<ServerFnTraitObj<$req, $res>>
.into_iter()
.map(|obj| {
((obj.path().to_string(), obj.method()), obj.clone())
})
.collect(),
)
})
};
}
@@ -984,7 +986,7 @@ impl<Req, Res> Clone for ServerFnTraitObj<Req, Res> {
#[allow(unused)] // used by server integrations
type LazyServerFnMap<Req, Res> =
LazyLock<DashMap<(String, Method), ServerFnTraitObj<Req, Res>>>;
LazyLock<RwLock<HashMap<(String, Method), ServerFnTraitObj<Req, Res>>>>;
#[cfg(feature = "ssr")]
impl<Req: 'static, Res: 'static> inventory::Collect
@@ -1006,6 +1008,7 @@ pub mod axum {
};
use axum::body::Body;
use http::{Method, Request, Response, StatusCode};
use or_poisoned::OrPoisoned;
use std::future::Future;
static REGISTERED_SERVER_FUNCTIONS: LazyServerFnMap<
@@ -1066,7 +1069,7 @@ pub mod axum {
>,
> + 'static,
{
REGISTERED_SERVER_FUNCTIONS.insert(
REGISTERED_SERVER_FUNCTIONS.write().or_poisoned().insert(
(T::PATH.into(), T::Protocol::METHOD),
ServerFnTraitObj::new::<T>(|req| Box::pin(T::run_on_server(req))),
);
@@ -1074,9 +1077,14 @@ pub mod axum {
/// The set of all registered server function paths.
pub fn server_fn_paths() -> impl Iterator<Item = (&'static str, Method)> {
REGISTERED_SERVER_FUNCTIONS
.iter()
let paths: Vec<_> = REGISTERED_SERVER_FUNCTIONS
.read()
.unwrap()
.values()
.map(|item| (item.path(), item.method()))
.collect();
paths.into_iter()
}
/// An Axum handler that responds to a server function request.
@@ -1110,14 +1118,18 @@ pub mod axum {
method: Method,
) -> Option<BoxedService<Request<Body>, Response<Body>>> {
let key = (path.into(), method);
REGISTERED_SERVER_FUNCTIONS.get(&key).map(|server_fn| {
let middleware = (server_fn.middleware)();
let mut service = server_fn.clone().boxed();
for middleware in middleware {
service = middleware.layer(service);
}
service
})
REGISTERED_SERVER_FUNCTIONS
.read()
.or_poisoned()
.get(&key)
.map(|server_fn| {
let middleware = (server_fn.middleware)();
let mut service = server_fn.clone().boxed();
for middleware in middleware {
service = middleware.layer(service);
}
service
})
}
}
@@ -1131,6 +1143,7 @@ pub mod actix {
};
use actix_web::{web::Payload, HttpRequest, HttpResponse};
use http::Method;
use or_poisoned::OrPoisoned;
#[doc(hidden)]
pub use send_wrapper::SendWrapper;
use std::future::Future;
@@ -1177,7 +1190,7 @@ pub mod actix {
>,
> + 'static,
{
REGISTERED_SERVER_FUNCTIONS.insert(
REGISTERED_SERVER_FUNCTIONS.write().or_poisoned().insert(
(T::PATH.into(), T::Protocol::METHOD),
ServerFnTraitObj::new::<T>(|req| Box::pin(T::run_on_server(req))),
);
@@ -1185,9 +1198,14 @@ pub mod actix {
/// The set of all registered server function paths.
pub fn server_fn_paths() -> impl Iterator<Item = (&'static str, Method)> {
REGISTERED_SERVER_FUNCTIONS
.iter()
let paths: Vec<_> = REGISTERED_SERVER_FUNCTIONS
.read()
.unwrap()
.values()
.map(|item| (item.path(), item.method()))
.collect();
paths.into_iter()
}
/// An Actix handler that responds to a server function request.
@@ -1236,16 +1254,18 @@ pub mod actix {
ActixMethod::CONNECT => Method::CONNECT,
_ => unreachable!(),
};
REGISTERED_SERVER_FUNCTIONS.get(&(path.into(), method)).map(
|server_fn| {
REGISTERED_SERVER_FUNCTIONS
.read()
.or_poisoned()
.get(&(path.into(), method))
.map(|server_fn| {
let middleware = (server_fn.middleware)();
let mut service = server_fn.clone().boxed();
for middleware in middleware {
service = middleware.layer(service);
}
service
},
)
})
}
}