Sorting out all sorts of feature flags etc. so everything will build and test

This commit is contained in:
Greg Johnston 2022-11-02 21:46:47 -04:00
parent 51142ad894
commit db69145fd9
23 changed files with 133 additions and 165 deletions

View File

@ -20,7 +20,6 @@ members = [
"examples/counters", "examples/counters",
"examples/counters-stable", "examples/counters-stable",
"examples/fetch", "examples/fetch",
"examples/gtk",
"examples/hackernews/hackernews-app", "examples/hackernews/hackernews-app",
"examples/hackernews/hackernews-client", "examples/hackernews/hackernews-client",
"examples/hackernews/hackernews-server", "examples/hackernews/hackernews-server",
@ -31,7 +30,9 @@ members = [
"examples/todomvc-ssr/todomvc-ssr-server", "examples/todomvc-ssr/todomvc-ssr-server",
] ]
exclude = [ exclude = [
"benchmarks" "benchmarks",
# not gonna lie, this is because my arm64 mac fails when linking a GTK binary
"examples/gtk",
] ]

View File

@ -6,12 +6,14 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
console_log = "0.2" console_log = "0.2"
leptos = { path = "../../../leptos", default-features = false, features = ["serde"] } leptos = { path = "../../../leptos", default-features = false, features = [
"serde",
] }
leptos_meta = { path = "../../../meta", default-features = false } leptos_meta = { path = "../../../meta", default-features = false }
leptos_router = { path = "../../../router", default-features = false } leptos_router = { path = "../../../router", default-features = false }
log = "0.4" log = "0.4"
gloo-net = { version = "0.2", features = ["http"] } gloo-net = { version = "0.2", features = ["http"] }
reqwest = { version = "0.11", features = ["json"], optional = true } reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
console_error_panic_hook = "0.1.7" console_error_panic_hook = "0.1.7"
@ -21,4 +23,4 @@ console_error_panic_hook = "0.1.7"
default = ["csr"] default = ["csr"]
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"] csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"] hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr", "dep:reqwest"] ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr"]

View File

@ -123,15 +123,3 @@ pub use leptos_server;
pub use leptos_server::*; pub use leptos_server::*;
pub use leptos_reactive::debug_warn; pub use leptos_reactive::debug_warn;
#[cfg(not(any(feature = "csr", feature = "ssr", feature = "hydrate")))]
compile_error!("set one of the following feature flags: 'csr', 'ssr' or 'hydrate'");
#[cfg(all(feature = "csr", feature = "ssr"))]
compile_error!("leptos features 'csr' and feature 'ssr' cannot be enabled at the same time");
#[cfg(all(feature = "csr", feature = "hydrate"))]
compile_error!("leptos features 'csr' and feature 'hydrate' cannot be enabled at the same time");
#[cfg(all(feature = "hydrate", feature = "ssr"))]
compile_error!("leptos features 'hydrate' and feature 'ssr' cannot be enabled at the same time");

View File

@ -1,15 +1,9 @@
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
mod for_component; mod for_component;
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
mod map; mod map;
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
mod suspense; mod suspense;
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
pub use for_component::*; pub use for_component::*;
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
pub use map::*; pub use map::*;
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
pub use suspense::*; pub use suspense::*;
pub trait Prop { pub trait Prop {

View File

@ -15,7 +15,6 @@ where
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[cfg(any(feature = "csr", feature = "hydrate", feature = "ssr"))]
pub fn Suspense<F, E, G>(cx: Scope, props: SuspenseProps<F, E, G>) -> impl Fn() -> Child pub fn Suspense<F, E, G>(cx: Scope, props: SuspenseProps<F, E, G>) -> impl Fn() -> Child
where where
F: IntoChild + Clone, F: IntoChild + Clone,
@ -32,17 +31,7 @@ where
render_suspense(cx, context, props.fallback.clone(), child) render_suspense(cx, context, props.fallback.clone(), child)
} }
#[cfg(not(any(feature = "csr", feature = "hydrate", feature = "ssr")))] #[cfg(any(feature = "csr", feature = "hydrate"))]
pub fn Suspense<F, E, G>(cx: Scope, props: SuspenseProps<F, E, G>) -> impl Fn() -> Child
where
F: IntoChild + Clone,
E: IntoChild,
G: Fn() -> E + 'static,
{
compile_error!("<Suspense/> can only be used when one of the following features is set on the `leptos` package: 'csr', 'ssr', or 'hydrate'");
}
#[cfg(not(feature = "ssr"))]
fn render_suspense<'a, F, E, G>( fn render_suspense<'a, F, E, G>(
cx: Scope, cx: Scope,
context: SuspenseContext, context: SuspenseContext,
@ -69,7 +58,7 @@ where
} }
} }
#[cfg(feature = "ssr")] #[cfg(not(any(feature = "csr", feature = "hydrate")))]
fn render_suspense<'a, F, E, G>( fn render_suspense<'a, F, E, G>(
cx: Scope, cx: Scope,
context: SuspenseContext, context: SuspenseContext,

View File

@ -177,19 +177,19 @@ cfg_if! {
if #[cfg(feature = "stable")] { if #[cfg(feature = "stable")] {
use leptos_reactive::{Memo, ReadSignal, RwSignal}; use leptos_reactive::{Memo, ReadSignal, RwSignal};
impl IntoChild for Memo<Vec<Element>> { impl IntoChild for Memo<Vec<crate::Element>> {
fn into_child(self, cx: Scope) -> Child { fn into_child(self, cx: Scope) -> Child {
(move || self.get()).into_child(cx) (move || self.get()).into_child(cx)
} }
} }
impl IntoChild for ReadSignal<Vec<Element>> { impl IntoChild for ReadSignal<Vec<crate::Element>> {
fn into_child(self, cx: Scope) -> Child { fn into_child(self, cx: Scope) -> Child {
(move || self.get()).into_child(cx) (move || self.get()).into_child(cx)
} }
} }
impl IntoChild for RwSignal<Vec<Element>> { impl IntoChild for RwSignal<Vec<crate::Element>> {
fn into_child(self, cx: Scope) -> Child { fn into_child(self, cx: Scope) -> Child {
(move || self.get()).into_child(cx) (move || self.get()).into_child(cx)
} }

View File

@ -5,6 +5,7 @@ pub mod child;
pub mod class; pub mod class;
pub mod event_delegation; pub mod event_delegation;
pub mod logging; pub mod logging;
pub mod mount;
pub mod operations; pub mod operations;
pub mod property; pub mod property;
@ -21,11 +22,9 @@ cfg_if! {
pub type Element = web_sys::Element; pub type Element = web_sys::Element;
pub type Node = web_sys::Node; pub type Node = web_sys::Node;
pub mod mount;
pub mod reconcile; pub mod reconcile;
pub mod render; pub mod render;
pub use mount::*;
pub use reconcile::*; pub use reconcile::*;
pub use render::*; pub use render::*;
} }
@ -35,6 +34,7 @@ pub use attribute::*;
pub use child::*; pub use child::*;
pub use class::*; pub use class::*;
pub use logging::*; pub use logging::*;
pub use mount::*;
pub use operations::*; pub use operations::*;
pub use property::*; pub use property::*;

View File

@ -1,4 +1,5 @@
use crate::{document, Element}; use crate::{document, Element};
use cfg_if::cfg_if;
use leptos_reactive::Scope; use leptos_reactive::Scope;
use wasm_bindgen::UnwrapThrowExt; use wasm_bindgen::UnwrapThrowExt;
@ -8,14 +9,22 @@ pub trait Mountable {
impl Mountable for Element { impl Mountable for Element {
fn mount(&self, parent: &web_sys::Element) { fn mount(&self, parent: &web_sys::Element) {
parent.append_child(self).unwrap_throw(); cfg_if! {
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
parent.append_child(self).unwrap_throw();
}
}
} }
} }
impl Mountable for Vec<Element> { impl Mountable for Vec<Element> {
fn mount(&self, parent: &web_sys::Element) { fn mount(&self, parent: &web_sys::Element) {
for element in self { cfg_if! {
parent.append_child(element).unwrap_throw(); if #[cfg(any(feature = "csr", feature = "hydrate"))] {
for element in self {
parent.append_child(element).unwrap_throw();
}
}
} }
} }
} }

View File

@ -84,7 +84,6 @@ impl SharedContext {
} }
} }
#[cfg(feature = "ssr")]
pub fn current_fragment_key(&self) -> String { pub fn current_fragment_key(&self) -> String {
if let Some(context) = &self.context { if let Some(context) = &self.context {
format!("{}{}f", context.id, context.count) format!("{}{}f", context.id, context.count)

View File

@ -561,7 +561,6 @@ where
}); });
} }
#[cfg(feature = "ssr")]
pub fn resource_to_serialization_resolver( pub fn resource_to_serialization_resolver(
&self, &self,
id: ResourceId, id: ResourceId,
@ -585,7 +584,6 @@ pub(crate) enum AnyResource {
pub(crate) trait SerializableResource { pub(crate) trait SerializableResource {
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;
#[cfg(feature = "ssr")]
fn to_serialization_resolver( fn to_serialization_resolver(
&self, &self,
id: ResourceId, id: ResourceId,
@ -601,7 +599,6 @@ where
self self
} }
#[cfg(feature = "ssr")]
fn to_serialization_resolver( fn to_serialization_resolver(
&self, &self,
id: ResourceId, id: ResourceId,

View File

@ -3,25 +3,20 @@ use crate::{
EffectId, Memo, ReadSignal, ResourceId, ResourceState, RwSignal, Scope, ScopeDisposer, ScopeId, EffectId, Memo, ReadSignal, ResourceId, ResourceState, RwSignal, Scope, ScopeDisposer, ScopeId,
ScopeProperty, SignalId, WriteSignal, ScopeProperty, SignalId, WriteSignal,
}; };
use cfg_if::cfg_if; use futures::stream::FuturesUnordered;
use slotmap::{SecondaryMap, SlotMap, SparseSecondaryMap}; use slotmap::{SecondaryMap, SlotMap, SparseSecondaryMap};
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
cell::{Cell, RefCell}, cell::{Cell, RefCell},
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fmt::Debug, fmt::Debug,
future::Future,
marker::PhantomData, marker::PhantomData,
pin::Pin,
rc::Rc, rc::Rc,
}; };
cfg_if! { pub(crate) type PinnedFuture<T> = Pin<Box<dyn Future<Output = T>>>;
if #[cfg(feature = "ssr")] {
use std::{future::Future, pin::Pin};
use futures::stream::FuturesUnordered;
pub(crate) type PinnedFuture<T> = Pin<Box<dyn Future<Output = T>>>;
}
}
#[derive(Default)] #[derive(Default)]
pub(crate) struct Runtime { pub(crate) struct Runtime {
@ -255,7 +250,6 @@ impl Runtime {
.collect() .collect()
} }
#[cfg(feature = "ssr")]
pub(crate) fn serialization_resolvers( pub(crate) fn serialization_resolvers(
&self, &self,
) -> FuturesUnordered<PinnedFuture<(ResourceId, String)>> { ) -> FuturesUnordered<PinnedFuture<(ResourceId, String)>> {

View File

@ -1,15 +1,11 @@
use cfg_if::cfg_if; use cfg_if::cfg_if;
use crate::{hydration::SharedContext, EffectId, ResourceId, Runtime, SignalId}; use crate::{hydration::SharedContext, EffectId, ResourceId, Runtime, SignalId};
use crate::{PinnedFuture, SuspenseContext};
use futures::stream::FuturesUnordered;
use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::{future::Future, pin::Pin};
cfg_if! {
if #[cfg(feature = "ssr")] {
use crate::{PinnedFuture, SuspenseContext};
use futures::stream::FuturesUnordered;
use std::{collections::HashMap, future::Future, pin::Pin};
}
}
#[must_use = "Scope will leak memory if the disposer function is never called"] #[must_use = "Scope will leak memory if the disposer function is never called"]
/// Creates a child reactive scope and runs the function within it. This is useful for applications /// Creates a child reactive scope and runs the function within it. This is useful for applications
@ -333,58 +329,54 @@ impl Scope {
self.runtime.all_resources() self.runtime.all_resources()
} }
cfg_if! { pub fn current_fragment_key(&self) -> String {
if #[cfg(feature = "ssr")] { self.runtime
/// Returns IDs for all [Resource](crate::Resource)s found on any scope. .shared_context
pub fn serialization_resolvers(&self) -> FuturesUnordered<PinnedFuture<(ResourceId, String)>> { .borrow()
self.runtime.serialization_resolvers() .as_ref()
} .map(|context| context.current_fragment_key())
.unwrap_or_else(|| String::from("0f"))
}
pub fn current_fragment_key(&self) -> String { /// Returns IDs for all [Resource](crate::Resource)s found on any scope.
self.runtime pub fn serialization_resolvers(&self) -> FuturesUnordered<PinnedFuture<(ResourceId, String)>> {
.shared_context self.runtime.serialization_resolvers()
.borrow() }
.as_ref()
.map(|context| context.current_fragment_key())
.unwrap_or_else(|| String::from("0f"))
}
pub fn register_suspense( pub fn register_suspense(
&self, &self,
context: SuspenseContext, context: SuspenseContext,
key: &str, key: &str,
resolver: impl FnOnce() -> String + 'static, resolver: impl FnOnce() -> String + 'static,
) { ) {
use crate::create_isomorphic_effect; use crate::create_isomorphic_effect;
use futures::StreamExt; use futures::StreamExt;
if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() { if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() {
let (mut tx, mut rx) = futures::channel::mpsc::channel::<()>(1); let (mut tx, mut rx) = futures::channel::mpsc::channel::<()>(1);
create_isomorphic_effect(*self, move |_| { create_isomorphic_effect(*self, move |_| {
let pending = context.pending_resources.try_with(|n| *n).unwrap_or(0); let pending = context.pending_resources.try_with(|n| *n).unwrap_or(0);
if pending == 0 { if pending == 0 {
_ = tx.try_send(()); _ = tx.try_send(());
}
});
shared_context.pending_fragments.insert(
key.to_string(),
Box::pin(async move {
rx.next().await;
resolver()
}),
);
} }
} });
pub fn pending_fragments(&self) -> HashMap<String, Pin<Box<dyn Future<Output = String>>>> { shared_context.pending_fragments.insert(
if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() { key.to_string(),
std::mem::take(&mut shared_context.pending_fragments) Box::pin(async move {
} else { rx.next().await;
HashMap::new() resolver()
} }),
} );
}
}
pub fn pending_fragments(&self) -> HashMap<String, Pin<Box<dyn Future<Output = String>>>> {
if let Some(ref mut shared_context) = *self.runtime.shared_context.borrow_mut() {
std::mem::take(&mut shared_context.pending_fragments)
} else {
HashMap::new()
} }
} }
} }

View File

@ -7,14 +7,14 @@ edition = "2021"
leptos_dom = { path = "../leptos_dom", default-features = false, version = "0.0.11" } leptos_dom = { path = "../leptos_dom", default-features = false, version = "0.0.11" }
leptos_reactive = { path = "../leptos_reactive", default-features = false, version = "0.0.11" } leptos_reactive = { path = "../leptos_reactive", default-features = false, version = "0.0.11" }
form_urlencoded = "1" form_urlencoded = "1"
gloo-net = { version = "0.2", optional = true } gloo-net = "0.2"
lazy_static = "1" lazy_static = "1"
linear-map = "1" linear-map = "1"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
thiserror = "1" thiserror = "1"
[features] [features]
csr = ["leptos_dom/csr", "leptos_reactive/csr", "dep:gloo-net"] csr = ["leptos_dom/csr", "leptos_reactive/csr"]
hydrate = ["leptos_dom/hydrate", "leptos_reactive/hydrate", "dep:gloo-net"] hydrate = ["leptos_dom/hydrate", "leptos_reactive/hydrate"]
ssr = ["leptos_dom/ssr", "leptos_reactive/ssr"] ssr = ["leptos_dom/ssr", "leptos_reactive/ssr"]
stable = ["leptos_dom/stable", "leptos_reactive/stable"] stable = ["leptos_dom/stable", "leptos_reactive/stable"]

View File

@ -69,7 +69,7 @@
pub use form_urlencoded; pub use form_urlencoded;
use leptos_reactive::*; use leptos_reactive::*;
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{future::Future, pin::Pin, rc::Rc}; use std::{future::Future, pin::Pin, rc::Rc};
use thiserror::Error; use thiserror::Error;
@ -174,7 +174,7 @@ pub enum ServerFnError {
MissingArg(String), MissingArg(String),
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
pub async fn call_server_fn<T>(url: &str, args: impl ServerFn) -> Result<T, ServerFnError> pub async fn call_server_fn<T>(url: &str, args: impl ServerFn) -> Result<T, ServerFnError>
where where
T: Serializable + Sized, T: Serializable + Sized,

View File

@ -9,6 +9,7 @@ description = "Router for the Leptos web framework."
[dependencies] [dependencies]
leptos = { path = "../leptos", version = "0.0", default-features = false } leptos = { path = "../leptos", version = "0.0", default-features = false }
cfg-if = "1"
common_macros = "0.1" common_macros = "0.1"
gloo-net = "0.2" gloo-net = "0.2"
itertools = "0.10" itertools = "0.10"
@ -21,9 +22,9 @@ url = { version = "2", optional = true }
urlencoding = "2" urlencoding = "2"
thiserror = "1" thiserror = "1"
typed-builder = "0.10" typed-builder = "0.10"
js-sys = { version = "0.3", optional = true } js-sys = { version = "0.3" }
wasm-bindgen = { version = "0.2", optional = true } wasm-bindgen = { version = "0.2" }
wasm-bindgen-futures = { version = "0.4", optional = true } wasm-bindgen-futures = { version = "0.4" }
[dependencies.web-sys] [dependencies.web-sys]
version = "0.3" version = "0.3"
@ -51,12 +52,7 @@ features = [
] ]
[features] [features]
default = ["csr"] default = []
csr = ["leptos/csr", "dep:js-sys", "dep:wasm-bindgen"] csr = ["leptos/csr"]
hydrate = [ hydrate = ["leptos/hydrate"]
"leptos/hydrate",
"dep:js-sys",
"dep:wasm-bindgen",
"dep:wasm-bindgen-futures",
]
ssr = ["leptos/ssr", "dep:url", "dep:regex"] ssr = ["leptos/ssr", "dep:url", "dep:regex"]

View File

@ -1,3 +1,4 @@
use cfg_if::cfg_if;
use leptos::leptos_dom::IntoChild; use leptos::leptos_dom::IntoChild;
use leptos::*; use leptos::*;
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;
@ -89,14 +90,27 @@ where
} }
let child = children.remove(0); let child = children.remove(0);
view! { cx, cfg_if! {
<a if #[cfg(any(feature = "csr", feature = "hydrate"))] {
href=move || href().unwrap_or_default() view! { cx,
prop:state={props.state.map(|s| s.to_js_value())} <a
prop:replace={props.replace} href=move || href().unwrap_or_default()
aria-current=move || if is_active() { Some("page") } else { None } prop:state={props.state.map(|s| s.to_js_value())}
> prop:replace={props.replace}
{child} aria-current=move || if is_active() { Some("page") } else { None }
</a> >
{child}
</a>
}
} else {
view! { cx,
<a
href=move || href().unwrap_or_default()
aria-current=move || if is_active() { Some("page") } else { None }
>
{child}
</a>
}
}
} }
} }

View File

@ -1,3 +1,4 @@
use cfg_if::cfg_if;
use std::ops::IndexMut; use std::ops::IndexMut;
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
@ -72,11 +73,14 @@ impl std::fmt::Debug for RouterContextInner {
impl RouterContext { impl RouterContext {
pub fn new(cx: Scope, base: Option<&'static str>, fallback: Option<fn() -> Element>) -> Self { pub fn new(cx: Scope, base: Option<&'static str>, fallback: Option<fn() -> Element>) -> Self {
#[cfg(any(feature = "csr", feature = "hydrate"))] cfg_if! {
let history = use_context::<RouterIntegrationContext>(cx) if #[cfg(any(feature = "csr", feature = "hydrate"))] {
.unwrap_or_else(|| RouterIntegrationContext(Rc::new(crate::BrowserIntegration {}))); let history = use_context::<RouterIntegrationContext>(cx)
#[cfg(not(any(feature = "csr", feature = "hydrate")))] .unwrap_or_else(|| RouterIntegrationContext(Rc::new(crate::BrowserIntegration {})));
let history = use_context::<RouterIntegrationContext>(cx).expect("You must call provide_context::<RouterIntegrationContext>(cx, ...) somewhere above the <Router/>."); } else {
let history = use_context::<RouterIntegrationContext>(cx).expect("You must call provide_context::<RouterIntegrationContext>(cx, ...) somewhere above the <Router/>.");
}
};
// Any `History` type gives a way to get a reactive signal of the current location // Any `History` type gives a way to get a reactive signal of the current location
// in the browser context, this is drawn from the `popstate` event // in the browser context, this is drawn from the `popstate` event
@ -143,7 +147,7 @@ impl RouterContext {
}); });
// handle all click events on anchor tags // handle all click events on anchor tags
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
leptos_dom::window_event_listener("click", { leptos_dom::window_event_listener("click", {
let inner = Rc::clone(&inner); let inner = Rc::clone(&inner);
move |ev| inner.clone().handle_anchor_click(ev) move |ev| inner.clone().handle_anchor_click(ev)
@ -253,7 +257,7 @@ impl RouterContextInner {
} }
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
pub(crate) fn handle_anchor_click(self: Rc<Self>, ev: web_sys::Event) { pub(crate) fn handle_anchor_click(self: Rc<Self>, ev: web_sys::Event) {
let ev = ev.unchecked_into::<web_sys::MouseEvent>(); let ev = ev.unchecked_into::<web_sys::MouseEvent>();
if ev.default_prevented() if ev.default_prevented()

View File

@ -184,7 +184,7 @@ impl std::fmt::Debug for Loader {
} }
} }
#[cfg(feature = "ssr")] #[cfg(all(feature = "ssr", not(feature = "hydrate")))]
pub async fn loader_to_json(view: impl Fn(Scope) -> String + 'static) -> Option<String> { pub async fn loader_to_json(view: impl Fn(Scope) -> String + 'static) -> Option<String> {
let (data, _, disposer) = run_scope_undisposed(move |cx| async move { let (data, _, disposer) = run_scope_undisposed(move |cx| async move {
let _shell = view(cx); let _shell = view(cx);

View File

@ -24,11 +24,9 @@ pub trait History {
fn navigate(&self, loc: &LocationChange); fn navigate(&self, loc: &LocationChange);
} }
#[cfg(any(feature = "csr", feature = "hydrate"))]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct BrowserIntegration {} pub struct BrowserIntegration {}
#[cfg(any(feature = "csr", feature = "hydrate"))]
impl BrowserIntegration { impl BrowserIntegration {
fn current() -> LocationChange { fn current() -> LocationChange {
let loc = leptos_dom::location(); let loc = leptos_dom::location();
@ -43,7 +41,6 @@ impl BrowserIntegration {
} }
} }
#[cfg(any(feature = "csr", feature = "hydrate"))]
impl History for BrowserIntegration { impl History for BrowserIntegration {
fn location(&self, cx: Scope) -> ReadSignal<LocationChange> { fn location(&self, cx: Scope) -> ReadSignal<LocationChange> {
use crate::{NavigateOptions, RouterContext}; use crate::{NavigateOptions, RouterContext};

View File

@ -1,16 +1,9 @@
#[cfg(not(feature = "ssr"))]
use leptos::wasm_bindgen::JsValue; use leptos::wasm_bindgen::JsValue;
#[derive(Debug, Clone, Default, PartialEq)] #[derive(Debug, Clone, Default, PartialEq)]
#[cfg(not(feature = "ssr"))]
pub struct State(pub Option<JsValue>); pub struct State(pub Option<JsValue>);
#[derive(Debug, Clone, Default, PartialEq)]
#[cfg(feature = "ssr")]
pub struct State(pub Option<()>);
impl State { impl State {
#[cfg(not(feature = "ssr"))]
pub fn to_js_value(&self) -> JsValue { pub fn to_js_value(&self) -> JsValue {
match &self.0 { match &self.0 {
Some(v) => v.clone(), Some(v) => v.clone(),
@ -19,7 +12,6 @@ impl State {
} }
} }
#[cfg(not(feature = "ssr"))]
impl<T> From<T> for State impl<T> From<T> for State
where where
T: Into<JsValue>, T: Into<JsValue>,

View File

@ -36,7 +36,7 @@ pub fn unescape(s: &str) -> String {
.replace('+', " ") .replace('+', " ")
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
pub fn unescape(s: &str) -> String { pub fn unescape(s: &str) -> String {
js_sys::decode_uri(s).unwrap().into() js_sys::decode_uri(s).unwrap().into()
} }
@ -46,12 +46,12 @@ pub fn escape(s: &str) -> String {
urlencoding::encode(s).into() urlencoding::encode(s).into()
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
pub fn escape(s: &str) -> String { pub fn escape(s: &str) -> String {
js_sys::encode_uri(s).as_string().unwrap() js_sys::encode_uri(s).as_string().unwrap()
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
impl TryFrom<&str> for Url { impl TryFrom<&str> for Url {
type Error = String; type Error = String;

View File

@ -1,7 +1,7 @@
use std::borrow::Cow; use std::borrow::Cow;
#[doc(hidden)] #[doc(hidden)]
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
pub fn expand_optionals(pattern: &str) -> Vec<Cow<str>> { pub fn expand_optionals(pattern: &str) -> Vec<Cow<str>> {
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;

View File

@ -44,7 +44,7 @@ fn has_scheme(path: &str) -> bool {
HAS_SCHEME_RE.is_match(path) HAS_SCHEME_RE.is_match(path)
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
fn has_scheme(path: &str) -> bool { fn has_scheme(path: &str) -> bool {
let re = js_sys::RegExp::new(HAS_SCHEME, ""); let re = js_sys::RegExp::new(HAS_SCHEME, "");
re.test(path) re.test(path)
@ -75,7 +75,7 @@ const BEGINS_WITH_QUERY_OR_HASH: &str = r#"^[?#]"#;
const HAS_SCHEME: &str = r#"^(?:[a-z0-9]+:)?//"#; const HAS_SCHEME: &str = r#"^(?:[a-z0-9]+:)?//"#;
const QUERY: &str = r#"/*(\*.*)?$"#; const QUERY: &str = r#"/*(\*.*)?$"#;
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
fn replace_trim_path<'a>(text: &'a str, replace: &str) -> Cow<'a, str> { fn replace_trim_path<'a>(text: &'a str, replace: &str) -> Cow<'a, str> {
let re = js_sys::RegExp::new(TRIM_PATH, "g"); let re = js_sys::RegExp::new(TRIM_PATH, "g");
js_sys::JsString::from(text) js_sys::JsString::from(text)
@ -85,13 +85,13 @@ fn replace_trim_path<'a>(text: &'a str, replace: &str) -> Cow<'a, str> {
.into() .into()
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
fn begins_with_query_or_hash(text: &str) -> bool { fn begins_with_query_or_hash(text: &str) -> bool {
let re = js_sys::RegExp::new(BEGINS_WITH_QUERY_OR_HASH, ""); let re = js_sys::RegExp::new(BEGINS_WITH_QUERY_OR_HASH, "");
re.test(text) re.test(text)
} }
#[cfg(any(feature = "csr", feature = "hydrate"))] #[cfg(not(feature = "ssr"))]
fn replace_query(text: &str) -> String { fn replace_query(text: &str) -> String {
let re = js_sys::RegExp::new(QUERY, "g"); let re = js_sys::RegExp::new(QUERY, "g");
js_sys::JsString::from(text) js_sys::JsString::from(text)