Compare commits

..

3 Commits

Author SHA1 Message Date
Greg Johnston
ab69750c01 fmt 2024-07-29 08:37:47 -04:00
Greg Johnston
b90fe273d5 remove unused import 2024-07-29 08:28:36 -04:00
Greg Johnston
5f0fab9f63 fix: untrack children in Portal to avoid re-triggering it accidentally 2024-07-24 12:23:07 -04:00
51 changed files with 266 additions and 342 deletions

View File

@@ -15,7 +15,7 @@ jobs:
test:
needs: [get-leptos-changed]
if: needs.get-leptos-changed.outputs.leptos_changed == 'true'
name: Run semver check (nightly-2024-07-21)
name: Run semver check (nightly-2024-04-14)
runs-on: ubuntu-latest
steps:
@@ -25,4 +25,4 @@ jobs:
- name: Semver Checks
uses: obi1kenobi/cargo-semver-checks-action@v2
with:
rust-toolchain: nightly-2024-07-21
rust-toolchain: nightly-2024-04-14

View File

@@ -40,4 +40,4 @@ jobs:
with:
directory: ${{ matrix.directory }}
cargo_make_task: "ci"
toolchain: nightly-2024-07-21
toolchain: nightly-2024-04-14

View File

@@ -28,24 +28,24 @@ members = [
exclude = ["benchmarks", "examples"]
[workspace.package]
version = "0.6.15"
version = "0.6.13"
rust-version = "1.75"
[workspace.dependencies]
oco_ref = { path = "./oco", version = "0.1.0" }
leptos = { path = "./leptos", version = "0.6.15" }
leptos_dom = { path = "./leptos_dom", version = "0.6.15" }
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.6.15" }
leptos_macro = { path = "./leptos_macro", version = "0.6.15" }
leptos_reactive = { path = "./leptos_reactive", version = "0.6.15" }
leptos_server = { path = "./leptos_server", version = "0.6.15" }
server_fn = { path = "./server_fn", version = "0.6.15" }
server_fn_macro = { path = "./server_fn_macro", version = "0.6.15" }
leptos = { path = "./leptos", version = "0.6.13" }
leptos_dom = { path = "./leptos_dom", version = "0.6.13" }
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.6.13" }
leptos_macro = { path = "./leptos_macro", version = "0.6.13" }
leptos_reactive = { path = "./leptos_reactive", version = "0.6.13" }
leptos_server = { path = "./leptos_server", version = "0.6.13" }
server_fn = { path = "./server_fn", version = "0.6.13" }
server_fn_macro = { path = "./server_fn_macro", version = "0.6.13" }
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.6" }
leptos_config = { path = "./leptos_config", version = "0.6.15" }
leptos_router = { path = "./router", version = "0.6.15" }
leptos_meta = { path = "./meta", version = "0.6.15" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.6.15" }
leptos_config = { path = "./leptos_config", version = "0.6.13" }
leptos_router = { path = "./router", version = "0.6.13" }
leptos_meta = { path = "./meta", version = "0.6.13" }
leptos_integration_utils = { path = "./integrations/utils", version = "0.6.13" }
[profile.release]
codegen-units = 1

View File

@@ -11,7 +11,7 @@ actix-files = { version = "0.6", optional = true }
actix-web = { version = "4", optional = true, features = ["macros"] }
console_error_panic_hook = "0.1"
cfg-if = "1"
http = { version = "1.0", optional = true }
http = { version = "0.2", optional = true }
leptos = { path = "../../leptos" }
leptos_meta = { path = "../../meta" }
leptos_actix = { path = "../../integrations/actix", optional = true }

View File

@@ -24,7 +24,7 @@ leptos_meta = { path = "../../meta" }
leptos_router = { path = "../../router" }
log = "0.4"
once_cell = "1.18"
gloo-net = { version = "0.6" }
gloo-net = { git = "https://github.com/rustwasm/gloo" }
wasm-bindgen = "0.2"
serde = { version = "1", features = ["derive"] }
simple_logger = "4.3"
@@ -33,13 +33,13 @@ tracing = { version = "0.1", optional = true }
[features]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
ssr = [
"dep:actix-files",
"dep:actix-web",
"dep:tracing",
"leptos/ssr",
"leptos_actix",
"leptos_meta/ssr",
"leptos_router/ssr",
"dep:actix-files",
"dep:actix-web",
"dep:tracing",
"leptos/ssr",
"leptos_actix",
"leptos_meta/ssr",
"leptos_router/ssr",
]
[package.metadata.cargo-all-features]

View File

@@ -22,4 +22,4 @@ rstest = "0.17.0"
[dev-dependencies.web-sys]
features = ["HtmlElement", "XPathResult"]
version = "0.3.70"
version = "0.3.61"

View File

@@ -23,7 +23,11 @@ pub fn copy_to_clipboard(el: HtmlElement<AnyElement>, content: &str) {
evt.prevent_default();
evt.stop_propagation();
let _ = window().navigator().clipboard().write_text(&content);
let _ = window()
.navigator()
.clipboard()
.expect("navigator.clipboard to be available")
.write_text(&content);
let _ = el.clone().inner_html(format!("Copied \"{}\"", &content));
});
@@ -72,13 +76,9 @@ pub fn App() -> impl IntoView {
let data = "Hello World!";
view! {
<a href="#" use:copy_to_clipboard=data>
"Copy \""
{data}
"\" to clipboard"
</a>
<a href="#" use:copy_to_clipboard=data>"Copy \"" {data} "\" to clipboard"</a>
// automatically applies the directive to every root element in `SomeComponent`
<SomeComponent use:highlight/>
<SomeComponent use:highlight />
// no value will default to `().into()`
<button use:add_dot>"Add a dot"</button>
// `5.into()` automatically called

View File

@@ -21,8 +21,8 @@ leptos_actix = { path = "../../integrations/actix", optional = true }
leptos_router = { path = "../../router" }
log = "0.4"
serde = { version = "1", features = ["derive"] }
gloo-net = { version = "0.6", features = ["http"] }
reqwest = { version = "0.12", features = ["json"] }
gloo-net = { version = "0.2", features = ["http"] }
reqwest = { version = "0.11", features = ["json"] }
tracing = "0.1"
# openssl = { version = "0.10", features = ["v110"] }
wasm-bindgen = "0.2"
@@ -32,12 +32,12 @@ web-sys = { version = "0.3", features = ["AbortController", "AbortSignal"] }
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
ssr = [
"dep:actix-files",
"dep:actix-web",
"dep:leptos_actix",
"leptos/ssr",
"leptos_meta/ssr",
"leptos_router/ssr",
"dep:actix-files",
"dep:actix-web",
"dep:leptos_actix",
"leptos/ssr",
"leptos_meta/ssr",
"leptos_router/ssr",
]
[profile.wasm-release]

View File

@@ -21,8 +21,8 @@ log = "0.4"
simple_logger = "4.0"
serde = { version = "1.0", features = ["derive"] }
tracing = "0.1"
gloo-net = { version = "0.6", features = ["http"] }
reqwest = { version = "0.12", features = ["json"] }
gloo-net = { version = "0.4", features = ["http"] }
reqwest = { version = "0.11", features = ["json"] }
axum = { version = "0.7", optional = true }
tower = { version = "0.4", optional = true }
tower-http = { version = "0.5", features = ["fs"], optional = true }

View File

@@ -13,18 +13,20 @@ lto = true
[dependencies]
console_log = "1.0"
console_error_panic_hook = "0.1"
leptos = { path = "../../leptos", features = ["experimental-islands"] }
leptos = { path = "../../leptos", features = [
"experimental-islands",
] }
leptos_axum = { path = "../../integrations/axum", optional = true, features = [
"experimental-islands",
] }
leptos_meta = { path = "../../meta" }
leptos_router = { path = "../../router" }
leptos_router = { path = "../../router"}
log = "0.4"
simple_logger = "4.0"
serde = { version = "1.0", features = ["derive"] }
tracing = "0.1"
gloo-net = { version = "0.6", features = ["http"] }
reqwest = { version = "0.12", features = ["json"] }
gloo-net = { version = "0.4", features = ["http"] }
reqwest = { version = "0.11", features = ["json"] }
axum = { version = "0.7", optional = true, features = ["http2"] }
tower = { version = "0.4", optional = true }
tower-http = { version = "0.5", features = [
@@ -37,11 +39,7 @@ http = { version = "1.0", optional = true }
web-sys = { version = "0.3", features = ["AbortController", "AbortSignal"] }
wasm-bindgen = "0.2"
lazy_static = "1.4.0"
rust-embed = { version = "8", features = [
"axum",
"mime_guess",
"tokio",
], optional = true }
rust-embed = { version = "8", features = ["axum", "mime_guess", "tokio"], optional = true }
mime_guess = { version = "2.0.4", optional = true }
[features]

View File

@@ -22,11 +22,11 @@ log = "0.4.17"
simple_logger = "4.0.0"
serde = { version = "1.0.148", features = ["derive"] }
tracing = "0.1"
gloo-net = { version = "0.6", features = ["http"] }
reqwest = { version = "0.12", features = ["json"] }
gloo-net = { version = "0.4.0", features = ["http"] }
reqwest = { version = "0.11.13", features = ["json"] }
axum = { version = "0.7", default-features = false, optional = true }
tower = { version = "0.4.13", optional = true }
http = { version = "1.0", optional = true }
http = { version = "0.2.11", optional = true }
web-sys = { version = "0.3", features = [
"AbortController",
"AbortSignal",

View File

@@ -14,7 +14,7 @@ leptos_router = { path = "../../../router", features = ["csr"] }
log = "0.4"
console_error_panic_hook = "0.1"
console_log = "1"
gloo-net = "0.6"
gloo-net = "0.5"
gloo-storage = "0.3"
serde = "1.0"
thiserror = "1.0"

View File

@@ -27,7 +27,7 @@ thiserror = "1.0"
wasm-bindgen = "0.2"
serde_toml = "0.0.1"
toml = "0.8.8"
web-sys = { version = "0.3.70", features = ["FileList", "File"] }
web-sys = { version = "0.3.67", features = ["FileList", "File"] }
strum = { version = "0.25.0", features = ["strum_macros", "derive"] }
notify = { version = "6.1.1", optional = true }
pin-project-lite = "0.2.13"

View File

@@ -27,39 +27,39 @@ tower-http = { version = "0.5", features = ["fs"], optional = true }
tokio = { version = "1.22.0", features = ["full"], optional = true }
http = { version = "1" }
sqlx = { version = "0.7", features = [
"runtime-tokio-rustls",
"sqlite",
"runtime-tokio-rustls",
"sqlite",
], optional = true }
thiserror = "1.0.38"
wasm-bindgen = "0.2"
axum_session_auth = { version = "0.12", features = [
"sqlite-rustls",
"sqlite-rustls",
], optional = true }
axum_session = { version = "0.12", features = [
"sqlite-rustls",
"sqlite-rustls",
], optional = true }
async-trait = { version = "0.1.64", optional = true }
reqwest = { version = "0.12", optional = true, features = ["json"] }
reqwest = { version = "0.11", optional = true, features = ["json"] }
[features]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
ssr = [
"dep:serde_json",
"dep:axum",
"dep:tower",
"dep:tower-http",
"dep:tokio",
"dep:reqwest",
"dep:oauth2",
"dep:axum_session_auth",
"dep:axum_session",
"dep:async-trait",
"dep:sqlx",
"dep:rand",
"leptos/ssr",
"leptos_meta/ssr",
"leptos_router/ssr",
"dep:leptos_axum",
"dep:serde_json",
"dep:axum",
"dep:tower",
"dep:tower-http",
"dep:tokio",
"dep:reqwest",
"dep:oauth2",
"dep:axum_session_auth",
"dep:axum_session",
"dep:async-trait",
"dep:sqlx",
"dep:rand",
"leptos/ssr",
"leptos_meta/ssr",
"leptos_router/ssr",
"dep:leptos_axum",
]
[package.metadata.cargo-all-features]

View File

@@ -13,7 +13,7 @@ leptos = { path = "../../leptos" }
leptos_actix = { path = "../../integrations/actix", optional = true }
leptos_meta = { path = "../../meta" }
leptos_router = { path = "../../router" }
gloo-net = { version = "0.6", features = ["http"] }
gloo-net = { version = "0.2", features = ["http"] }
log = "0.4"
# dependencies for client (enable when csr or hydrate set)

View File

@@ -8,7 +8,7 @@ leptos = { path = "../../leptos", features = ["csr"] }
leptos_meta = { path = "../../meta", features = ["csr"] }
leptos_router = { path = "../../router", features = ["csr"] }
log = "0.4"
gloo-net = { version = "0.6", features = ["http"] }
gloo-net = { version = "0.5", features = ["http"] }
# dependencies for client (enable when csr or hydrate set)
wasm-bindgen = { version = "0.2" }

View File

@@ -15,7 +15,7 @@ console_error_panic_hook = "0.1.7"
uuid = { version = "1", features = ["v4", "js", "serde"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
web-sys = { version = "0.3.70", features = ["Storage"] }
web-sys = { version = "0.3.60", features = ["Storage"] }
[dev-dependencies]
wasm-bindgen-test = "0.3.0"

View File

@@ -1030,8 +1030,6 @@ where
let full_path = format!("http://leptos.dev{path}");
let (tx, rx) = futures::channel::oneshot::channel();
let current_span = tracing::Span::current();
spawn_task!(async move {
let app = {
let full_path = full_path.clone();
@@ -1065,7 +1063,7 @@ where
*writable = new_res_parts;
_ = tx.send(html);
}.instrument(current_span));
});
let html = rx.await.expect("to complete HTML rendering");
@@ -1862,4 +1860,3 @@ where
.await
.map_err(|e| ServerFnError::ServerError(format!("{e:?}")))
}

View File

@@ -136,7 +136,7 @@ pub fn html_parts_separated(
idle(() => {{
import('{pkg_path}/{output_name}{js_hash}.js')
.then(mod => {{
mod.default({{module_or_path: '{pkg_path}/{wasm_output_name}{wasm_hash}.wasm'}}).then({import_callback});
mod.default('{pkg_path}/{wasm_output_name}{wasm_hash}.wasm').then({import_callback});
}})
}});
</script>

View File

@@ -28,7 +28,7 @@ server_fn = { workspace = true, features = [
"url",
"cbor",
] }
web-sys = { version = "0.3.70", features = [
web-sys = { version = "0.3.63", features = [
"ShadowRoot",
"ShadowRootInit",
"ShadowRootMode",

View File

@@ -112,7 +112,7 @@ pub fn request_animation_frame(cb: impl FnOnce() + 'static) {
// Closure::once_into_js only frees the callback when it's actually
// called, so this instead uses into_js_value, which can be freed by
// the host JS engine's GC if it supports weak references (which all
// modern browser engines do). The way this works is that the provided
// modern brower engines do). The way this works is that the provided
// callback's captured data is dropped immediately after being called,
// as before, but it leaves behind a small stub closure rust-side that
// will be freed "eventually" by the JS GC. If the function is never

View File

@@ -1211,17 +1211,6 @@ impl IntoView for Rc<str> {
}
}
impl IntoView for std::sync::Arc<str> {
#[cfg_attr(
any(debug_assertions, feature = "ssr"),
instrument(level = "trace", name = "#text", skip_all)
)]
#[inline(always)]
fn into_view(self) -> View {
View::Text(Text::new(self.into()))
}
}
impl IntoView for Oco<'static, str> {
#[cfg_attr(
any(debug_assertions, feature = "ssr"),

View File

@@ -18,7 +18,7 @@ cfg-if = "1"
html-escape = "0.2"
itertools = "0.12"
prettyplease = "0.2.4"
proc-macro-error2 = { version = "2", default-features = false }
proc-macro-error = { version = "1", default-features = false }
proc-macro2 = "1"
quote = "1"
syn = { version = "2", features = ["full"] }

View File

@@ -11,13 +11,13 @@ dependencies = [
[tasks.test-leptos_macro-example]
description = "Tests the leptos_macro/example to check if macro handles doc comments correctly"
command = "cargo"
args = ["+nightly-2024-07-21", "test", "--doc"]
args = ["+nightly-2024-04-14", "test", "--doc"]
cwd = "example"
install_crate = false
[tasks.doc-leptos_macro-example]
description = "Docs the leptos_macro/example to check if macro handles doc comments correctly"
command = "cargo"
args = ["+nightly-2024-07-21", "doc"]
args = ["+nightly-2024-04-14", "doc"]
cwd = "example"
install_crate = false

View File

@@ -128,7 +128,7 @@ impl ToTokens for Model {
_ => None,
});
if let Some(semi) = ends_semi {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
semi.span(),
"A component that ends with a `view!` macro followed by a \
semicolon will return (), an empty view. This is usually \
@@ -416,61 +416,41 @@ impl ToTokens for Model {
let island_props = if is_island_with_children
|| is_island_with_other_props
{
let (destructure, prop_builders, optional_props) =
if is_island_with_other_props {
let prop_names = props
.iter()
.filter_map(|prop| {
if prop.name.ident == "children" {
None
} else {
let name = &prop.name.ident;
Some(quote! { #name, })
}
})
.collect::<TokenStream>();
let destructure = quote! {
let #props_serialized_name {
#prop_names
} = props;
};
let prop_builders = props
.iter()
.filter_map(|prop| {
if prop.name.ident == "children"
|| prop.prop_opts.optional
{
None
} else {
let name = &prop.name.ident;
Some(quote! {
.#name(#name)
})
}
})
.collect::<TokenStream>();
let optional_props = props
.iter()
.filter_map(|prop| {
if prop.name.ident == "children"
|| !prop.prop_opts.optional
{
None
} else {
let name = &prop.name.ident;
Some(quote! {
if let Some(#name) = #name {
props.#name = Some(#name)
}
})
}
})
.collect::<TokenStream>();
(destructure, prop_builders, optional_props)
} else {
(quote! {}, quote! {}, quote! {})
let (destructure, prop_builders) = if is_island_with_other_props
{
let prop_names = props
.iter()
.filter_map(|prop| {
if prop.name.ident == "children" {
None
} else {
let name = &prop.name.ident;
Some(quote! { #name, })
}
})
.collect::<TokenStream>();
let destructure = quote! {
let #props_serialized_name {
#prop_names
} = props;
};
let prop_builders = props
.iter()
.filter_map(|prop| {
if prop.name.ident == "children" {
None
} else {
let name = &prop.name.ident;
Some(quote! {
.#name(#name)
})
}
})
.collect::<TokenStream>();
(destructure, prop_builders)
} else {
(quote! {}, quote! {})
};
let children = if is_island_with_children {
quote! {
.children(::std::boxed::Box::new(move || ::leptos::Fragment::lazy(|| ::std::vec![
@@ -489,13 +469,10 @@ impl ToTokens for Model {
quote! {{
#destructure
let mut props = #props_name::builder()
#props_name::builder()
#prop_builders
#children.build();
#optional_props
props
#children
.build()
}}
} else {
quote! {}

View File

@@ -7,7 +7,7 @@
#![allow(private_macro_use)]
#[macro_use]
extern crate proc_macro_error2;
extern crate proc_macro_error;
use component::DummyModel;
use proc_macro::TokenStream;
@@ -313,7 +313,7 @@ mod slot;
/// # ;
/// # }
/// ```
#[proc_macro_error2::proc_macro_error]
#[proc_macro_error::proc_macro_error]
#[proc_macro]
#[cfg_attr(
any(debug_assertions, feature = "ssr"),
@@ -391,7 +391,7 @@ fn normalized_call_site(site: proc_macro::Span) -> Option<String> {
/// syntax as the [view!] macro. In hydration or server-side rendering mode,
/// behaves exactly as the `view` macro. In client-side rendering mode, uses a `<template>`
/// node to efficiently render the element. Should only be used with a single root element.
#[proc_macro_error2::proc_macro_error]
#[proc_macro_error::proc_macro_error]
#[proc_macro]
pub fn template(tokens: TokenStream) -> TokenStream {
if cfg!(feature = "csr") {
@@ -583,7 +583,7 @@ pub fn template(tokens: TokenStream) -> TokenStream {
/// }
/// }
/// ```
#[proc_macro_error2::proc_macro_error]
#[proc_macro_error::proc_macro_error]
#[proc_macro_attribute]
pub fn component(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
let is_transparent = if !args.is_empty() {
@@ -699,7 +699,7 @@ pub fn component(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
/// }
/// }
/// ```
#[proc_macro_error2::proc_macro_error]
#[proc_macro_error::proc_macro_error]
#[proc_macro_attribute]
pub fn island(_args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
let Ok(mut dummy) = syn::parse::<DummyModel>(s.clone()) else {
@@ -839,7 +839,7 @@ pub fn island(_args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
/// }
/// }
/// ```
#[proc_macro_error2::proc_macro_error]
#[proc_macro_error::proc_macro_error]
#[proc_macro_attribute]
pub fn slot(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
if !args.is_empty() {

View File

@@ -43,6 +43,7 @@ pub(crate) fn fragment_to_tokens(
let mut nodes = nodes
.iter()
.filter_map(|node| {
let span = node.span();
let node = node_to_tokens(
node,
parent_type,
@@ -51,8 +52,10 @@ pub(crate) fn fragment_to_tokens(
None,
)?;
let node = quote_spanned!(span => { #node });
Some(quote! {
::leptos::IntoView::into_view(#[allow(unused_braces)] { #node })
::leptos::IntoView::into_view(#[allow(unused_braces)] #node)
})
})
.peekable();
@@ -132,7 +135,7 @@ pub(crate) fn node_to_tokens(
Node::RawText(r) => {
let text = r.to_string_best();
if text == "cx," {
proc_macro_error2::abort!(
proc_macro_error::abort!(
r.span(),
"`cx,` is not used with the `view!` macro in 0.5."
)
@@ -185,7 +188,7 @@ pub(crate) fn element_to_tokens(
match parent_type {
TagType::Unknown => {
// We decided this warning was too aggressive, but I'll leave it here in case we want it later
/* proc_macro_error2::emit_warning!(name.span(), "The view macro is assuming this is an HTML element, \
/* proc_macro_error::emit_warning!(name.span(), "The view macro is assuming this is an HTML element, \
but it is ambiguous; if it is an SVG or MathML element, prefix with svg:: or math::"); */
quote! {
::leptos::leptos_dom::html::#name()
@@ -282,7 +285,7 @@ pub(crate) fn element_to_tokens(
};
if is_self_closing(node) && !node.children.is_empty() {
proc_macro_error2::abort!(
proc_macro_error::abort!(
node.name().span(),
format!(
"<{tag}> is a self-closing tag and cannot have children."
@@ -303,7 +306,9 @@ pub(crate) fn element_to_tokens(
global_class,
None,
)
.unwrap_or(quote! { ::leptos::leptos_dom::Unit }),
.unwrap_or(quote_spanned! {
Span::call_site()=> ::leptos::leptos_dom::Unit
}),
),
Node::Text(node) => Some(quote! { #node }),
Node::RawText(node) => {
@@ -332,17 +337,16 @@ pub(crate) fn element_to_tokens(
quote! {}
};
let ide_helper_close_tag = ide_helper_close_tag.into_iter();
let result = quote! {
{
#(#ide_helper_close_tag)*
#name
#(#attrs)*
#(#bindings)*
#(#class_attrs)*
#(#style_attrs)*
#global_class_expr
#(#children)*
#view_marker
let result = quote_spanned! {node.span()=> {
#(#ide_helper_close_tag)*
#name
#(#attrs)*
#(#bindings)*
#(#class_attrs)*
#(#style_attrs)*
#global_class_expr
#(#children)*
#view_marker
}
};
@@ -402,14 +406,18 @@ pub(crate) fn attribute_to_tokens(
let event_type = if is_custom {
event_type
} else if let Some(ev_name) = event_name_ident {
quote! { #ev_name }
quote_spanned! {
ev_name.span()=> #ev_name
}
} else {
event_type
};
let event_type = if is_force_undelegated {
let undelegated = if let Some(undelegated) = undelegated_ident {
quote! { #undelegated }
quote_spanned! {
undelegated.span()=> #undelegated
}
} else {
quote! { undelegated }
};
@@ -470,7 +478,7 @@ pub(crate) fn attribute_to_tokens(
&& node.value().and_then(value_to_string).is_none()
{
let span = node.key.span();
proc_macro_error2::emit_error!(span, "Combining a global class (view! { class = ... }) \
proc_macro_error::emit_error!(span, "Combining a global class (view! { class = ... }) \
and a dynamic `class=` attribute on an element causes runtime inconsistencies. You can \
toggle individual classes dynamically with the `class:name=value` syntax. \n\nSee this issue \
for more information and an example: https://github.com/leptos-rs/leptos/issues/773")

View File

@@ -384,7 +384,7 @@ fn child_to_tokens(
match node {
Node::Element(node) => {
if is_component_node(node) {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
node.name().span(),
"component children not allowed in template!, use view! \
instead"

View File

@@ -6,7 +6,7 @@ use super::{
};
use crate::view::directive_call_from_attribute_node;
use proc_macro2::{Ident, TokenStream, TokenTree};
use quote::{format_ident, quote, quote_spanned, ToTokens};
use quote::{format_ident, quote, quote_spanned};
use rstml::node::{NodeAttribute, NodeElement};
use std::collections::HashMap;
use syn::spanned::Spanned;
@@ -70,8 +70,10 @@ pub(crate) fn component_to_tokens(
})
.unwrap_or_else(|| quote! { #name });
quote! {
.#name(#[allow(unused_braces)] { #value })
let value = quote_spanned!(value.span()=> { #value });
quote_spanned! {attr.span()=>
.#name(#[allow(unused_braces)] #value)
}
});
@@ -100,13 +102,7 @@ pub(crate) fn component_to_tokens(
.filter(|attr| attr.key.to_string().starts_with("on:"))
.map(|attr| {
let (event_type, handler) = event_from_attribute_node(attr, true);
// HACK(chrisp60): rstml and leptos has a different definition on attribute keys.
// This retains precise span information for the "on" in "on:some_event_name".
//
// A similar hack is done in `event_from_attribute_node` to retain the precise
// event name span.
let on = attr.key.to_token_stream().into_iter().next();
let on = quote_spanned!(attr.key.span()=> on);
quote! {
.#on(#event_type, #handler)
}
@@ -173,7 +169,8 @@ pub(crate) fn component_to_tokens(
items_to_bind.iter().map(|ident| quote! { #ident, });
let clonables = items_to_clone.iter().map(|ident| {
quote! { let #ident = ::core::clone::Clone::clone(&#ident); }
let ident_ref = quote_spanned!(ident.span()=> &#ident);
quote! { let #ident = ::core::clone::Clone::clone(#ident_ref); }
});
if bindables.len() > 0 {
@@ -205,7 +202,7 @@ pub(crate) fn component_to_tokens(
.span();
let slot = Ident::new(&slot, span);
let value = if values.len() > 1 {
quote! {
quote_spanned! {span=>
::std::vec![
#(#values)*
]
@@ -224,16 +221,28 @@ pub(crate) fn component_to_tokens(
quote! {}
};
let name_ref = quote_spanned! {name.span()=>
&#name
};
let build = quote_spanned! {name.span()=>
.build()
};
let component_props_builder = quote_spanned! {name.span()=>
::leptos::component_props_builder(#name_ref #generics)
};
#[allow(unused_mut)] // used in debug
let mut component = quote! {
let mut component = quote_spanned! {node.span()=>
::leptos::component_view(
#[allow(clippy::needless_borrows_for_generic_args)]
&#name,
::leptos::component_props_builder(&#name #generics)
#name_ref,
#component_props_builder
#(#props)*
#(#slots)*
#children
.build()
#build
#dyn_attrs
#(#spread_bindings)*
)
@@ -247,7 +256,7 @@ pub(crate) fn component_to_tokens(
if events_and_directives.is_empty() {
component
} else {
quote! {
quote_spanned! {node.span()=>
::leptos::IntoView::into_view(#[allow(unused_braces)] {#component})
#(#events_and_directives)*
}

View File

@@ -25,7 +25,7 @@ impl IdeTagHelper {
/// Emit warning if tag is component.
pub fn save_tag_completion(&mut self, name: &NodeName) {
if is_component_tag_name(name) {
proc_macro_error2::emit_warning!(
proc_macro_error::emit_warning!(
name.span(),
"BUG: Component tag is used in regular tag completion."
);

View File

@@ -1,7 +1,7 @@
use crate::{attribute_value, Mode};
use convert_case::{Case::Snake, Casing};
use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use quote::{quote, quote_spanned, ToTokens};
use quote::{quote, quote_spanned};
use rstml::node::{KeyedAttribute, Node, NodeElement, NodeName};
use syn::{
spanned::Spanned,
@@ -439,7 +439,7 @@ fn fancy_class_name<'a>(
}
_ => {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
elem.span(),
"class name elements must be string \
literals"
@@ -459,7 +459,7 @@ fn fancy_class_name<'a>(
}
_ => {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
class_name.span(),
"class name must be a string literal or array of \
string literals"
@@ -475,7 +475,7 @@ fn fancy_class_name<'a>(
}
}
} else {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
tuple.span(),
"class tuples must have two elements."
)
@@ -496,7 +496,7 @@ fn ident_from_tag_name(tag_name: &NodeName) -> Ident {
.expect("element needs to have a name"),
NodeName::Block(_) => {
let span = tag_name.span();
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
span,
"blocks not allowed in tag-name position"
);
@@ -529,7 +529,7 @@ fn fancy_style_name<'a>(
{
s.value()
} else {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
style_name.span(),
"style name must be a string literal"
);
@@ -544,7 +544,7 @@ fn fancy_style_name<'a>(
value,
));
} else {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
tuple.span(),
"style tuples must have two elements."
)
@@ -567,41 +567,12 @@ pub(crate) fn event_from_attribute_node(
let handler = attribute_value(attr);
let (event_type, is_custom, name_undelegated) =
parse_event_name(&event_name);
// HACK(chrisp60): in the code above, the original span information is lost
// as the event name is parsed from a stringified version of the tokens.
//
// This assumes that the attribute key is structured as "on:some_event_name" and
// just skips the "on:" part, isolating the "some_event_name" tokens. In turn,
// we keep the span information from the original event identifier.
//
// .nth(2) is because syn parses follows
// token 0: "on"
// token 1: ":"
// token 2: "event"
//
// There are cleaners ways to do this but this is a legacy branch.
let original_tokens = attr
.key
.to_token_stream()
.into_iter()
.nth(2)
.expect("tokens following on:"); // see previous call to .expect in this same function
// is_custom wraps the event type in a struct definition, so don't use
// our original tokens.
let absolute_ev = if is_custom {
quote! { ::leptos::leptos_dom::ev::#event_type }
} else {
quote! { ::leptos::leptos_dom::ev::#original_tokens }
};
let (event_type, _, name_undelegated) = parse_event_name(&event_name);
let event_type = if force_undelegated || name_undelegated {
quote! { ::leptos::leptos_dom::ev::undelegated(#absolute_ev) }
quote! { ::leptos::leptos_dom::ev::undelegated(::leptos::leptos_dom::ev::#event_type) }
} else {
quote! { ::leptos::leptos_dom::ev::#absolute_ev }
quote! { ::leptos::leptos_dom::ev::#event_type }
};
(event_type, handler)
}

View File

@@ -81,14 +81,16 @@ pub(crate) fn fragment_to_tokens_ssr(
};
let nodes = nodes.iter().map(|node| {
let span = node.span();
let node = root_node_to_tokens_ssr(node, global_class, None);
let node = quote_spanned!(span=> { #node });
quote! {
::leptos::IntoView::into_view(#[allow(unused_braces)] { #node })
::leptos::IntoView::into_view(#[allow(unused_braces)] #node)
}
});
quote! {
quote_spanned! {original_span=>
{
::leptos::Fragment::lazy(|| ::std::vec![
#(#nodes),*
@@ -464,7 +466,7 @@ fn attribute_to_tokens_ssr<'a>(
&& attr.value().and_then(value_to_string).is_none()
{
let span = attr.key.span();
proc_macro_error2::emit_error!(span, "Combining a global class (view! { class = ... }) \
proc_macro_error::emit_error!(span, "Combining a global class (view! { class = ... }) \
and a dynamic `class=` attribute on an element causes runtime inconsistencies. You can \
toggle individual classes dynamically with the `class:name=value` syntax. \n\nSee this issue \
for more information and an example: https://github.com/leptos-rs/leptos/issues/773")

View File

@@ -25,7 +25,7 @@ pub(crate) fn slot_to_tokens(
let component_name = ident_from_tag_name(node.name());
let Some(parent_slots) = parent_slots else {
proc_macro_error2::emit_error!(
proc_macro_error::emit_error!(
node.name().span(),
"slots cannot be used inside HTML elements"
);
@@ -61,8 +61,10 @@ pub(crate) fn slot_to_tokens(
})
.unwrap_or_else(|| quote! { #name });
quote! {
.#name(#[allow(unused_braces)] { #value })
let value = quote_spanned!(value.span()=> { #value });
quote_spanned! {attr.span()=>
.#name(#[allow(unused_braces)] #value)
}
});
@@ -166,7 +168,7 @@ pub(crate) fn slot_to_tokens(
.span();
let slot = Ident::new(&slot, span);
let value = if values.len() > 1 {
quote! {
quote_spanned! {span=>
::std::vec![
#(#values)*
]

View File

@@ -174,7 +174,7 @@ where
///
/// Unlike a "derived signal," a memo comes with two guarantees:
/// 1. The memo will only run *once* per change, no matter how many times you
/// access its value.
/// access its value.
/// 2. The memo will only notify its dependents if the value of the computation changes.
///
/// This makes a memo the perfect tool for expensive computations.
@@ -190,11 +190,11 @@ where
/// - [`.get()`](#impl-SignalGet<T>-for-Memo<T>) (or calling the signal as a function) clones the current
/// value of the signal. If you call it within an effect, it will cause that effect
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-Memo<T>) clones the value of the signal
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-Memo<T>) clones the value of the signal
/// without reactively tracking it.
/// - [`.with()`](#impl-SignalWith<T>-for-Memo<T>) allows you to reactively access the signals value without
/// cloning by applying a callback function.
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-Memo<T>) allows you to access the signals
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-Memo<T>) allows you to access the signals
/// value without reactively tracking it.
/// - [`.to_stream()`](#impl-SignalStream<T>-for-Memo<T>) converts the signal to an `async` stream of values.
///

View File

@@ -394,11 +394,11 @@ pub fn create_signal_from_stream<T>(
/// - [`.get()`](#impl-SignalGet<T>-for-ReadSignal<T>) (or calling the signal as a function) clones the current
/// value of the signal. If you call it within an effect, it will cause that effect
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-ReadSignal<T>) clones the value of the signal
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-ReadSignal<T>) clones the value of the signal
/// without reactively tracking it.
/// - [`.with()`](#impl-SignalWith<T>-for-ReadSignal<T>) allows you to reactively access the signals value without
/// cloning by applying a callback function.
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-ReadSignal<T>) allows you to access the signals
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-ReadSignal<T>) allows you to access the signals
/// value without reactively tracking it.
/// - [`.to_stream()`](#impl-SignalStream<T>-for-ReadSignal<T>) converts the signal to an `async` stream of values.
///
@@ -817,11 +817,11 @@ impl<T> Hash for ReadSignal<T> {
/// - [`.set()`](#impl-SignalSet<T>-for-WriteSignal<T>) (or calling the setter as a function)
/// sets the signals value, and notifies all subscribers that the signals value has changed.
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.set_untracked()`](#impl-SignalSetUntracked<T>-for-WriteSignal<T>) sets the signals value
/// - [`.set_untracked()`](#impl-SignalSetUntracked<T>-for-WriteSignal<T>) sets the signals value
/// without notifying its subscribers.
/// - [`.update()`](#impl-SignalUpdate<T>-for-WriteSignal<T>) mutates the signals value in place
/// and notifies all subscribers that the signals value has changed.
/// - [`.update_untracked()`](#impl-SignalUpdateUntracked<T>-for-WriteSignal<T>) mutates the signals value
/// - [`.update_untracked()`](#impl-SignalUpdateUntracked<T>-for-WriteSignal<T>) mutates the signals value
/// in place without notifying its subscribers.
///
/// ## Examples
@@ -1165,20 +1165,20 @@ pub fn create_rw_signal<T>(value: T) -> RwSignal<T> {
/// - [`.get()`](#impl-SignalGet<T>-for-RwSignal<T>) clones the current
/// value of the signal. If you call it within an effect, it will cause that effect
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-RwSignal<T>) clones the value of the signal
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-RwSignal<T>) clones the value of the signal
/// without reactively tracking it.
/// - [`.with()`](#impl-SignalWith<T>-for-RwSignal<T>) allows you to reactively access the signals value without
/// cloning by applying a callback function.
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-RwSignal<T>) allows you to access the signals
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-RwSignal<T>) allows you to access the signals
/// value without reactively tracking it.
/// - [`.set()`](#impl-SignalSet<T>-for-RwSignal<T>) sets the signals value,
/// and notifies all subscribers that the signals value has changed.
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.set_untracked()`](#impl-SignalSetUntracked<T>-for-RwSignal<T>) sets the signals value
/// - [`.set_untracked()`](#impl-SignalSetUntracked<T>-for-RwSignal<T>) sets the signals value
/// without notifying its subscribers.
/// - [`.update()`](#impl-SignalUpdate<T>-for-RwSignal<T>) mutates the signals value in place
/// and notifies all subscribers that the signals value has changed.
/// - [`.update_untracked()`](#impl-SignalUpdateUntracked<T>-for-RwSignal<T>) mutates the signals value
/// - [`.update_untracked()`](#impl-SignalUpdateUntracked<T>-for-RwSignal<T>) mutates the signals value
/// in place without notifying its subscribers.
/// - [`.to_stream()`](#impl-SignalStream<T>-for-RwSignal<T>) converts the signal to an `async` stream of values.
///

View File

@@ -46,11 +46,11 @@ where
/// - [`.get()`](#impl-SignalGet-for-Signal<T>) (or calling the signal as a function) clones the current
/// value of the signal. If you call it within an effect, it will cause that effect
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-Signal<T>) clones the value of the signal
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-Signal<T>) clones the value of the signal
/// without reactively tracking it.
/// - [`.with()`](#impl-SignalWith-for-Signal<T>) allows you to reactively access the signals value without
/// cloning by applying a callback function.
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-Signal<T>) allows you to access the signals
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-Signal<T>) allows you to access the signals
/// value without reactively tracking it.
/// - [`.to_stream()`](#impl-SignalStream<T>-for-Signal<T>) converts the signal to an `async` stream of values.
///
@@ -494,11 +494,11 @@ impl<T> Eq for SignalTypes<T> where T: PartialEq {}
/// - [`.get()`](#impl-SignalGet-for-MaybeSignal<T>) (or calling the signal as a function) clones the current
/// value of the signal. If you call it within an effect, it will cause that effect
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-MaybeSignal<T>) clones the value of the signal
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-MaybeSignal<T>) clones the value of the signal
/// without reactively tracking it.
/// - [`.with()`](#impl-SignalWith-for-MaybeSignal<T>) allows you to reactively access the signals value without
/// cloning by applying a callback function.
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-MaybeSignal<T>) allows you to access the signals
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-MaybeSignal<T>) allows you to access the signals
/// value without reactively tracking it.
/// - [`.to_stream()`](#impl-SignalStream<T>-for-MaybeSignal<T>) converts the signal to an `async` stream of values.
///
@@ -889,11 +889,11 @@ where
/// value of the signal. If you call it within an effect, it will cause that effect
/// to subscribe to the signal, and to re-run whenever the value of the signal changes.
/// - [`.get_untracked()`](#impl-SignalGetUntracked<T>-for-MaybeProp<T>) clones the value of the signal
/// without reactively tracking it.
/// without reactively tracking it.
/// - [`.with()`](#impl-SignalWith-for-MaybeProp<T>) allows you to reactively access the signals value without
/// cloning by applying a callback function.
/// - [`.with_untracked()`](#impl-SignalWithUntracked<T>-for-MaybeProp<T>) allows you to access the signals
/// value without reactively tracking it.
/// value without reactively tracking it.
/// - [`.to_stream()`](#impl-SignalStream<T>-for-MaybeProp<T>) converts the signal to an `async` stream of values.
///
/// ## Examples

View File

@@ -108,7 +108,7 @@
////! HTML forms dont support `PUT` or `DELETE`, and they dont support sending JSON. This means that if you use anything
////! but a `GET` or `POST` request with URL-encoded data, it can only work once WASM has loaded.
////!
////! The CBOR encoding is supported for historical reasons; an earlier version of server functions used a URL encoding that
////! The CBOR encoding is suported for historical reasons; an earlier version of server functions used a URL encoding that
////! didnt support nested objects like structs or vectors as server function arguments, which CBOR did. But note that the
////! CBOR forms encounter the same issue as `PUT`, `DELETE`, or JSON: they do not degrade gracefully if the WASM version of
////! your app is not available.

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_meta"
version = "0.6.15"
version = "0.6.13"
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"

View File

@@ -42,7 +42,6 @@ use std::{
ops::{Add, Deref},
path::Path,
rc::Rc,
sync::Arc,
};
/// "Owned Clones Once": a smart pointer that can be either a reference,
@@ -68,8 +67,6 @@ pub enum Oco<'a, T: ?Sized + ToOwned + 'a> {
Borrowed(&'a T),
/// A reference counted pointer to a value.
Counted(Rc<T>),
/// A reference atomically-counted pointer to a value.
AtomicallyCounted(Arc<T>),
/// An owned value.
Owned(<T as ToOwned>::Owned),
}
@@ -80,7 +77,6 @@ impl<'a, T: ?Sized + ToOwned> Oco<'a, T> {
match self {
Oco::Borrowed(v) => v.to_owned(),
Oco::Counted(v) => v.as_ref().to_owned(),
Oco::AtomicallyCounted(v) => v.as_ref().to_owned(),
Oco::Owned(v) => v,
}
}
@@ -133,7 +129,6 @@ impl<T: ?Sized + ToOwned> Deref for Oco<'_, T> {
Oco::Borrowed(v) => v,
Oco::Owned(v) => v.borrow(),
Oco::Counted(v) => v,
Oco::AtomicallyCounted(v) => v,
}
}
}
@@ -284,7 +279,6 @@ where
match self {
Self::Borrowed(v) => Self::Borrowed(v),
Self::Counted(v) => Self::Counted(Rc::clone(v)),
Self::AtomicallyCounted(v) => Self::AtomicallyCounted(Arc::clone(v)),
Self::Owned(v) => Self::Counted(Rc::from(v.borrow())),
}
}
@@ -310,7 +304,6 @@ where
match &*self {
Self::Borrowed(v) => Self::Borrowed(v),
Self::Counted(v) => Self::Counted(Rc::clone(v)),
Self::AtomicallyCounted(v) => Self::AtomicallyCounted(Arc::clone(v)),
Self::Owned(v) => {
let rc = Rc::from(v.borrow());
*self = Self::Counted(rc.clone());
@@ -420,7 +413,6 @@ where
Oco::Borrowed(v) => Cow::Borrowed(v),
Oco::Owned(v) => Cow::Owned(v),
Oco::Counted(v) => Cow::Owned(v.as_ref().to_owned()),
Oco::AtomicallyCounted(v) => Cow::Owned(v.as_ref().to_owned()),
}
}
}
@@ -434,15 +426,6 @@ where
}
}
impl<T: ?Sized> From<Arc<T>> for Oco<'_, T>
where
T: ToOwned,
{
fn from(v: Arc<T>) -> Self {
Oco::AtomicallyCounted(v)
}
}
impl<T: ?Sized> From<Box<T>> for Oco<'_, T>
where
T: ToOwned,
@@ -463,7 +446,6 @@ impl From<Oco<'_, str>> for String {
match v {
Oco::Borrowed(v) => v.to_owned(),
Oco::Counted(v) => v.as_ref().to_owned(),
Oco::AtomicallyCounted(v) => v.as_ref().to_owned(),
Oco::Owned(v) => v,
}
}
@@ -493,7 +475,6 @@ impl<'a> From<Oco<'a, str>> for Oco<'a, [u8]> {
Oco::Borrowed(v) => Oco::Borrowed(v.as_bytes()),
Oco::Owned(v) => Oco::Owned(v.into_bytes()),
Oco::Counted(v) => Oco::Counted(v.into()),
Oco::AtomicallyCounted(v) => Oco::AtomicallyCounted(v.into()),
}
}
}

View File

@@ -8,9 +8,9 @@ codegen-units = 1
lto = true
[dependencies]
leptos = { version = "0.6.15", features = ["csr"] }
leptos_meta = { version = "0.6.15", features = ["csr"] }
leptos_router = { version = "0.6.15", features = ["csr"] }
leptos = { version = "0.6.13", features = ["csr"] }
leptos_meta = { version = "0.6.13", features = ["csr"] }
leptos_router = { version = "0.6.13", features = ["csr"] }
console_log = "1"
log = "0.4"
console_error_panic_hook = "0.1.7"

View File

@@ -37,7 +37,7 @@ pub fn make_openapi_call_via_gpt(message:String) -> ChatCompletionParameters {
// This name will be given to the OpenAI API as part of our functions
let name = operation.operation_id.clone().expect("Each operation to have an operation id");
// we'll use the description
// we'll use the descrition
let desc = operation.description.clone().expect("Each operation to have a description, this is how GPT knows what the functiond does and it is helpful for calling it.");
let mut required_list = vec![];
let mut properties = serde_json::Map::new();

View File

@@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = ["app", "frontend", "ids", "server", "e2e"]
members = ["app", "frontend", "ids", "server","e2e"]
# need to be applied only to wasm build
[profile.release]
@@ -13,38 +13,34 @@ leptos = { version = "0.6.9", features = ["nightly"] }
leptos_meta = { version = "0.6.9", features = ["nightly"] }
leptos_router = { version = "0.6.9", features = ["nightly"] }
leptos_axum = { version = "0.6.9" }
leptos-use = { version = "0.10.5" }
leptos-use = {version = "0.10.5"}
axum = "0.7"
axum-server = { version = "0.6", features = ["tls-rustls"] }
axum-extra = { version = "0.9.2", features = ["cookie"] }
axum-server = {version = "0.6", features = ["tls-rustls"]}
axum-extra = { version = "0.9.2", features=["cookie"]}
cfg-if = "1"
console_error_panic_hook = "0.1.7"
console_log = "1"
http = "1"
ids = { path = "./ids" }
ids = {path="./ids"}
# this goes to this personal branch because of https://github.com/ory/sdk/issues/325#issuecomment-1960834676
ory-kratos-client = { git = "https://github.com/sjud/kratos-client-rust" }
ory-keto-client = { version = "0.11.0-alpha.0" }
reqwest = { version = "0.12", features = ["json", "cookies"] }
ory-kratos-client = {git="https://github.com/sjud/kratos-client-rust"}
ory-keto-client = {version = "0.11.0-alpha.0"}
reqwest = { version = "0.11.24", features = ["json","cookies"] }
serde = "1.0.197"
serde_json = "1.0.114"
sqlx = { version = "0.7.3", features = ["runtime-tokio", "sqlite", "macros"] }
sqlx = {version= "0.7.3", features=["runtime-tokio","sqlite","macros"]}
thiserror = "1"
time = "0.3.34"
tokio = { version = "1.33.0", features = ["full"] }
tower = { version = "0.4.13", features = ["full"] }
tower-http = { version = "0.5", features = ["full"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tracing-subscriber = {version="0.3.18", features=["env-filter"]}
url = "2.5.0"
uuid = { version = "1.7.0", features = ["v4", "serde"] }
uuid = {version = "1.7.0", features=["v4","serde"]}
wasm-bindgen = "0.2.92"
web-sys = { version = "0.3.69", features = [
"HtmlDocument",
"HtmlFormElement",
"FormData",
] }
web-sys = {version = "0.3.69", features=["HtmlDocument","HtmlFormElement","FormData"]}
# See https://github.com/akesson/cargo-leptos for documentation of all the parameters.

View File

@@ -93,7 +93,7 @@ pub fn kratos_html(node: UiNode, body: RwSignal<HashMap<String, String>>) -> imp
body.update(|map| {
_ = map.insert(name.clone(), value.clone());
});
// this expects the identifier to be an email, but it could be telephone etc so code is extra fragile
// this expects the identifer to be an email, but it could be telelphone etc so code is extra fragile
view! {<input type="hidden" value=value name=name /> }.into_view()
}
}

View File

@@ -6,21 +6,19 @@ edition = "2021"
[dev-dependencies]
anyhow = "1.0.72"
async-trait = "0.1.72"
cucumber = { version = "0.20.2", features = ["tracing", "macros"] }
cucumber = {version="0.20.2",features=["tracing","macros"]}
pretty_assertions = "1.4.0"
serde_json = "1.0.104"
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread", "time"] }
url = "2.4.0"
reqwest = "0.12"
reqwest = "0.11.25"
tracing = "0.1.40"
chromiumoxide = { version = "0.5.7", default-features = false, features = [
"tokio-runtime",
] }
chromiumoxide = {version = "0.5.7", default-features = false, features=["tokio-runtime"]}
ids.workspace = true
fake = "2.9.2"
tokio-tungstenite = "0.21.0"
futures-util = "0.3.30"
uuid = { version = "1.7.0", features = ["serde"] }
uuid = {version="1.7.0",features=["serde"]}
once_cell = "1.19.0"
futures = "0.3.30"
@@ -30,9 +28,13 @@ harness = false # Allow Cucumber to print output instead of libtest
[features]
#vscode thing to get autocomplete
ssr = []
ssr=[]
[dependencies]
once_cell = "1.19.0"
regex = "1.10.3"
serde.workspace = true

View File

@@ -27,7 +27,7 @@ pub static LOGOUT_BUTTON_ID: &'static str = "logout_button_id";
pub static LOGIN_BUTTON_ID: &'static str = "login_button_id";
/// This function is for use in kratos_html, it takes the name of the input node and it
/// matches it according to what we've specified in the kratos schema file. If we change the schema.
/// I.e use a phone instead of an email, the identifier id will change and break tests that expect an email.
/// I.e use a phone instead of an email, the identifer id will change and break tests that expect an email.
/// i.e use oidc instead of password, as auth method... that will break tests too.
/// Which is good.
pub fn match_name_to_id(name: String) -> &'static str {

View File

@@ -5,7 +5,7 @@ First
cargo new leptos_tauri_from_scratch
```
Then, make our two separate project folders. We need one for our actual app, 'src-orig' and the other is required when using `cargo tauri`
Then, make our two seperate project folders. We need one for our actual app, 'src-orig' and the other is required when using `cargo tauri`
```sh
mkdir src-orig && mkdir src-tauri
```

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_router"
version = "0.6.15"
version = "0.6.13"
edition = "2021"
authors = ["Greg Johnston", "Ben Wishovich"]
license = "MIT"
@@ -15,7 +15,7 @@ leptos_integration_utils = { workspace = true, optional = true }
leptos_meta = { workspace = true, optional = true }
cached = { version = "0.45.0", optional = true }
cfg-if = "1"
gloo-net = { version = "0.6", features = ["http"] }
gloo-net = { version = "0.5", features = ["http"] }
lazy_static = "1"
linear-map = { version = "1", features = ["serde_impl"] }
once_cell = "1.18"

View File

@@ -322,15 +322,11 @@ impl RouterContextInner {
let resolved = resolved_to.to_string();
let state = options.state.clone();
set_reference.update(move |r| *r = resolved);
// batch these so the history update is atomic
batch(|| {
set_reference.update(move |r| *r = resolved);
set_state.update({
let next_state = state.clone();
move |state| *state = next_state
});
set_state.update({
let next_state = state.clone();
move |state| *state = next_state
});
let global_suspense =

View File

@@ -14,7 +14,7 @@ server_fn_macro_default = { workspace = true }
# used for hashing paths in #[server] macro
const_format = "0.2"
xxhash-rust = { version = "0.8", features = ["const_xxh64"] }
# used across multiple features
# used across multiple featurs
serde = { version = "1", features = ["derive"] }
send_wrapper = { version = "0.6", features = ["futures"], optional = true }
@@ -57,7 +57,7 @@ rkyv = { version = "0.7", features = [
rmp-serde = { version = "1.1", optional = true }
# client
gloo-net = { version = "0.6", optional = true }
gloo-net = { version = "0.5", optional = true }
js-sys = { version = "0.3", optional = true }
wasm-bindgen = { version = "0.2", optional = true }
wasm-bindgen-futures = { version = "0.4", optional = true }
@@ -69,7 +69,7 @@ web-sys = { version = "0.3", optional = true, features = [
] }
# reqwest client
reqwest = { version = "0.12", default-features = false, optional = true, features = [
reqwest = { version = "0.11", default-features = false, optional = true, features = [
"multipart",
"stream",
] }

View File

@@ -40,8 +40,7 @@ where
{
async fn from_req(req: Request) -> Result<Self, ServerFnError<CustErr>> {
let string_data = req.as_query().unwrap_or_default();
let args = serde_qs::Config::new(5, false)
.deserialize_str::<Self>(string_data)
let args = serde_qs::from_str::<Self>(string_data)
.map_err(|e| ServerFnError::Args(e.to_string()))?;
Ok(args)
}
@@ -75,8 +74,7 @@ where
{
async fn from_req(req: Request) -> Result<Self, ServerFnError<CustErr>> {
let string_data = req.try_into_string().await?;
let args = serde_qs::Config::new(5, false)
.deserialize_str::<Self>(&string_data)
let args = serde_qs::from_str::<Self>(&string_data)
.map_err(|e| ServerFnError::Args(e.to_string()))?;
Ok(args)
}

View File

@@ -192,10 +192,8 @@ fn streaming_request(
let headers = Headers::new()?;
headers.append("Content-Type", content_type)?;
headers.append("Accept", accepts)?;
let init = RequestInit::new();
init.set_headers(&headers);
init.set_method("POST");
init.set_body(&stream);
let mut init = RequestInit::new();
init.headers(&headers).method("POST").body(Some(&stream));
// Chrome requires setting `duplex: "half"` on streaming requests
Reflect::set(