Compare commits

...

26 Commits

Author SHA1 Message Date
Greg Johnston
a6b6864bc5 Merge branch 'adjust-tracing' of https://github.com/gbj/leptos into adjust-tracing 2023-01-07 16:27:33 -05:00
Greg Johnston
063b946cd4 Remove unnecessary log 2023-01-07 16:27:25 -05:00
Greg Johnston
5a2c9ea345 Merge branch 'main' into adjust-tracing 2023-01-07 16:26:20 -05:00
Greg Johnston
808d87598b Tracing for events and elements. 2023-01-07 16:20:00 -05:00
Greg Johnston
0956c48b1e Merge pull request #266 from gbj/fix-meta-panic
Adjust default features for `meta` and `router`
2023-01-07 14:44:23 -05:00
Greg Johnston
8915e2615b Adjust default features for meta and router 2023-01-07 14:43:32 -05:00
Greg Johnston
7f47134058 Merge pull request #265 from martinfrances107/needless_borrowed_reference
Clippy: Minor needless_borrowed_reference.
2023-01-07 14:21:58 -05:00
Greg Johnston
af7b93fa1e Merge pull request #128 from akesson/workspace-features
Workspace features
2023-01-07 14:19:56 -05:00
Greg Johnston
ed940f577a Add tracing for event handlers 2023-01-07 13:32:40 -05:00
Martin
916f30a07b Clippy: Minor needless_borrowed_reference. 2023-01-07 18:28:42 +00:00
Greg Johnston
e01c565de1 Improve tracing formatting 2023-01-07 13:16:30 -05:00
Greg Johnston
dffe195cdc Fix two warnings 2023-01-07 13:16:20 -05:00
Greg Johnston
a5e2587555 Merge pull request #261 from martinfrances107/Clippy_removed_clone_where_possible
Clippy: Removed stray calls to .clone().
2023-01-07 12:47:06 -05:00
Greg Johnston
af8889fab2 Merge pull request #262 from martinfrances107/uninlined_format_args
Minor: Clippy format!() all variables now inlined.
2023-01-07 12:42:56 -05:00
Greg Johnston
267c1cfc34 Merge pull request #263 from martinfrances107/if_let_some
Removed clippy::single_match issue.
2023-01-07 12:40:55 -05:00
Greg Johnston
3498378e60 Merge pull request #260 from jquesada2016/into_signal_traits
added `IntoSignal` and `IntoSignalSetter` helper traits
2023-01-07 12:40:15 -05:00
hakesson
f8c680d14d Integrations with workspace dependencies 2023-01-07 18:05:35 +01:00
hakesson
b852e459a9 Unify workspace dependencies 2023-01-07 18:00:37 +01:00
hakesson
681f10ec8d Workspace-based versioning 2023-01-07 17:35:02 +01:00
Martin
1d480791a1 Removed clippy::single_match issue. 2023-01-07 16:08:17 +00:00
Martin
7acc309f66 Minor: Clippy format!() all variables now inlined. 2023-01-07 15:46:47 +00:00
Martin
9527de15ed Removed stray calls to .clone(). 2023-01-07 14:53:59 +00:00
Jose Quesada
aeb25a715a added IntoSignal and IntoSignalSetter helper traits 2023-01-07 08:20:27 -06:00
Greg Johnston
46e91a538c Merge branch 'main' of https://github.com/gbj/leptos 2023-01-07 08:32:45 -05:00
Greg Johnston
1fe526c99c Remove erroneous log 2023-01-07 08:32:39 -05:00
Greg Johnston
6b05918807 Merge pull request #257 from gbj/ci-disk-space
Improve CI disk space usage
2023-01-07 07:44:10 -05:00
32 changed files with 387 additions and 181 deletions

View File

@@ -23,10 +23,23 @@ members = [
]
exclude = ["benchmarks", "examples"]
[workspace.package]
version = "0.1.0-beta"
[workspace.dependencies]
leptos = { path = "./leptos", default-features = false, version = "0.1.0-beta" }
leptos_dom = { path = "./leptos_dom", default-features = false, version = "0.1.0-beta" }
leptos_macro = { path = "./leptos_macro", default-features = false, version = "0.1.0-beta" }
leptos_reactive = { path = "./leptos_reactive", default-features = false, version = "0.1.0-beta" }
leptos_server = { path = "./leptos_server", default-features = false, version = "0.1.0-beta" }
leptos_config = { path = "./leptos_config", default-features = false, version = "0.1.0-beta" }
leptos_router = { path = "./router", version = "0.1.0-beta" }
leptos_meta = { path = "./meta", default-feature = false, version = "0.1.0-beta" }
[profile.release]
codegen-units = 1
lto = true
opt-level = 'z'
[workspace.metadata.cargo-all-features]
skip_feature_sets = [["csr", "ssr"], ["csr", "hydrate"], ["ssr", "hydrate"]]
skip_feature_sets = [["csr", "ssr"], ["csr", "hydrate"], ["ssr", "hydrate"]]

View File

@@ -7,11 +7,11 @@ edition = "2021"
console_log = "0.2"
log = "0.4"
leptos = { path = "../../leptos" }
leptos_router = { path = "../../router", features=["csr"] }
leptos_router = { path = "../../router", features = ["csr"] }
serde = { version = "1", features = ["derive"] }
futures = "0.3"
console_error_panic_hook = "0.1.7"
leptos_meta = { path = "../../meta", default-features = false }
leptos_meta = { path = "../../meta", features = ["csr"] }
[dev-dependencies]
wasm-bindgen-test = "0.3.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_actix"
version = "0.1.0-beta"
version.workspace = true
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
@@ -10,13 +10,7 @@ description = "Actix integrations for the Leptos web framework."
[dependencies]
actix-web = "4"
futures = "0.3"
leptos = { path = "../../leptos", default-features = false, version = "0.1.0-alpha", features = [
"ssr",
] }
leptos_meta = { path = "../../meta", default-features = false, version = "0.1.0-alpha", features = [
"ssr",
] }
leptos_router = { path = "../../router", default-features = false, version = "0.1.0-alpha", features = [
"ssr",
] }
leptos = { workspace = true, features = ["ssr"] }
leptos_meta = { workspace = true, features = ["ssr"] }
leptos_router = { workspace = true, features = ["ssr"] }
tokio = { version = "1.0", features = ["full"] }

View File

@@ -290,7 +290,7 @@ where IV: IntoView
// the site was built with cargo run and not cargo-leptos
let bundle_path = match site_root.as_ref() {
"pkg" => "pkg".to_string(),
_ => format!("{}/{}", site_root, pkg_path),
_ => format!("{site_root}/{pkg_path}"),
};
let leptos_autoreload = match std::env::var("LEPTOS_WATCH").is_ok() {
@@ -358,7 +358,7 @@ where IV: IntoView
let res_options = res_options.0.read().await;
let (status, mut headers) = (res_options.status.clone(), res_options.headers.clone());
let (status, mut headers) = (res_options.status, res_options.headers.clone());
let status = status.unwrap_or_default();
let complete_stream =

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_axum"
version = "0.1.0-beta"
version.workspace = true
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
@@ -8,20 +8,14 @@ repository = "https://github.com/gbj/leptos"
description = "Axum integrations for the Leptos web framework."
[dependencies]
axum = {version="0.6", features=["macros"]}
axum = { version = "0.6", features = ["macros"] }
derive_builder = "0.12.0"
futures = "0.3"
http = "0.2.8"
hyper = "0.14.23"
kdl = "4.6.0"
leptos = { path = "../../leptos", default-features = false, version = "0.1.0-beta", features = [
"ssr",
] }
leptos_meta = { path = "../../meta", default-features = false, version = "0.1.0-beta", features = [
"ssr",
] }
leptos_router = { path = "../../router", default-features = false, version = "0.1.0-beta", features = [
"ssr",
] }
leptos_config = { path = "../../leptos_config", default-features = false, version = "0.1.0-beta" }
leptos = { workspace = true, features = ["ssr"] }
leptos_meta = { workspace = true, features = ["ssr"] }
leptos_router = { workspace = true, features = ["ssr"] }
leptos_config.workspace = true
tokio = { version = "1.0", features = ["full"] }

View File

@@ -139,7 +139,7 @@ pub async fn handle_server_fns(
req: Request<Body>,
) -> impl IntoResponse {
// Axum Path extractor doesn't remove the first slash from the path, while Actix does
let fn_name: String = match fn_name.strip_prefix("/") {
let fn_name: String = match fn_name.strip_prefix('/') {
Some(path) => path.to_string(),
None => fn_name,
};
@@ -180,15 +180,12 @@ pub async fn handle_server_fns(
let res_options_outer = res_options.unwrap().0;
let res_options_inner = res_options_outer.read().await;
let (status, mut res_headers) = (
res_options_inner.status.clone(),
res_options_inner.status,
res_options_inner.headers.clone(),
);
match res.headers_mut() {
Some(header_ref) => {
header_ref.extend(res_headers.drain());
}
None => (),
if let Some(header_ref) = res.headers_mut() {
header_ref.extend(res_headers.drain());
};
if accept_header == Some("application/json")
@@ -237,9 +234,9 @@ pub async fn handle_server_fns(
Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Full::from(
format!("Could not find a server function at the route {:?}. \
format!("Could not find a server function at the route {fn_name}. \
\n\nIt's likely that you need to call ServerFn::register() on the \
server function type, somewhere in your `main` function.", fn_name)
server function type, somewhere in your `main` function." )
))
}
.expect("could not build Response");
@@ -339,7 +336,7 @@ where
// the site was built with cargo run and not cargo-leptos
let bundle_path = match site_root.as_ref() {
"pkg" => "pkg".to_string(),
_ => format!("{}/{}", site_root, pkg_path),
_ => format!("{site_root}/{pkg_path}"),
};
let output_name = &options.output_name;
@@ -487,10 +484,9 @@ where
Box::pin(complete_stream) as PinnedHtmlStream
));
match res_options.status {
Some(status) => *res.status_mut() = status,
None => (),
};
if let Some(status) = res_options.status {
*res.status_mut() = status
}
let mut res_headers = res_options.headers.clone();
res.headers_mut().extend(res_headers.drain());

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos"
version = "0.1.0-beta"
version.workspace = true
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
@@ -10,11 +10,11 @@ readme = "../README.md"
[dependencies]
cfg-if = "1"
leptos_config = { path = "../leptos_config", default-features = false, version = "0.1.0-beta" }
leptos_dom = { path = "../leptos_dom", default-features = false, version = "0.1.0-beta" }
leptos_macro = { path = "../leptos_macro", default-features = false, version = "0.1.0-beta" }
leptos_reactive = { path = "../leptos_reactive", default-features = false, version = "0.1.0-beta" }
leptos_server = { path = "../leptos_server", default-features = false, version = "0.1.0-beta" }
leptos_dom.workspace = true
leptos_macro.workspace = true
leptos_reactive.workspace = true
leptos_server.workspace = true
leptos_config.workspace = true
tracing = "0.1"
typed-builder = "0.11"

View File

@@ -119,8 +119,7 @@ impl TryFrom<String> for Env {
"prod" => Ok(Self::PROD),
"production" => Ok(Self::PROD),
other => Err(format!(
"{} is not a supported environment. Use either `dev` or `production`.",
other
"{other} is not a supported environment. Use either `dev` or `production`."
)),
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_dom"
version = "0.1.0-beta"
version.workspace = true
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
@@ -17,7 +17,7 @@ html-escape = "0.2"
indexmap = "1.9"
itertools = "0.10"
js-sys = "0.3"
leptos_reactive = { path = "../leptos_reactive", default-features = false, version = "0.1.0-beta" }
leptos_reactive.workspace = true
once_cell = "1"
pad-adapter = "0.1"
paste = "1"

View File

@@ -43,6 +43,7 @@ fn view_fn(cx: Scope) -> impl IntoView {
let (is_a, set_is_a) = create_signal(cx, true);
let handle_toggle = move |_| {
trace!("toggling");
if is_a() {
set_b(a());
@@ -91,5 +92,8 @@ fn Example(cx: Scope) -> impl IntoView {
view! { cx,
<h1>"Example"</h1>
<button on:click=move |_| set_value.update(|value| *value += 1)>
"Click me"
</button>
}
}

View File

@@ -154,10 +154,7 @@ where
let component = DynChildRepr::new();
#[cfg(all(target_arch = "wasm32", feature = "web"))]
let (frag, closing) = (
component.document_fragment.clone(),
component.closing.node.clone(),
);
let closing = component.closing.node.clone();
let child = component.child.clone();
@@ -189,7 +186,9 @@ where
// or to reuse it in the case of a text node
// TODO check does this still detect moves correctly?
let was_child_moved = prev_t.is_none() && child.get_closing_node().next_sibling().as_ref() != Some(&closing);
let was_child_moved = prev_t.is_none()
&& child.get_closing_node().next_sibling().as_ref()
!= Some(&closing);
// If the previous child was a text node, we would like to
// make use of it again if our current child is also a text

View File

@@ -16,10 +16,20 @@ thread_local! {
pub fn add_event_listener<E>(
target: &web_sys::Element,
event_name: Cow<'static, str>,
cb: impl FnMut(E) + 'static,
mut cb: impl FnMut(E) + 'static,
) where
E: FromWasmAbi + 'static,
{
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let cb = move |e| {
let _guard = span.enter();
cb(e);
};
}
}
let cb = Closure::wrap(Box::new(cb) as Box<dyn FnMut(E)>).into_js_value();
let key = event_delegation_key(&event_name);
_ = js_sys::Reflect::set(target, &JsValue::from_str(&key), &cb);
@@ -31,10 +41,20 @@ pub fn add_event_listener<E>(
pub fn add_event_listener_undelegated<E>(
target: &web_sys::Element,
event_name: &str,
cb: impl FnMut(E) + 'static,
mut cb: impl FnMut(E) + 'static,
) where
E: FromWasmAbi + 'static,
{
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let cb = move |e| {
let _guard = span.enter();
cb(e);
};
}
}
let event_name = intern(event_name);
let cb = Closure::wrap(Box::new(cb) as Box<dyn FnMut(E)>).into_js_value();
_ = target.add_event_listener_with_callback(event_name, cb.unchecked_ref());
@@ -97,7 +117,20 @@ pub(crate) fn add_delegated_event_listener(event_name: Cow<'static, str>) {
}
};
crate::window_event_listener(&event_name, handler);
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let handler = move |e| {
let _guard = span.enter();
handler(e);
};
}
}
let handler = Box::new(handler) as Box<dyn FnMut(web_sys::Event)>;
let handler = Closure::wrap(handler).into_js_value();
_ = crate::window()
.add_event_listener_with_callback(&event_name, handler.unchecked_ref());
// register that we've created handler
events.insert(event_name);

View File

@@ -71,21 +71,57 @@ pub fn event_target_checked(ev: &web_sys::Event) -> bool {
/// Runs the given function between the next repaint
/// using [`Window.requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))]
pub fn request_animation_frame(cb: impl FnOnce() + 'static) {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let cb = move || {
let _guard = span.enter();
cb();
};
}
}
let cb = Closure::once_into_js(cb);
_ = window().request_animation_frame(cb.as_ref().unchecked_ref());
}
/// Queues the given function during an idle period
/// using [`Window.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestIdleCallback).
#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))]
pub fn request_idle_callback(cb: impl Fn() + 'static) {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let cb = move || {
let _guard = span.enter();
cb();
};
}
}
let cb = Closure::wrap(Box::new(cb) as Box<dyn Fn()>).into_js_value();
_ = window().request_idle_callback(cb.as_ref().unchecked_ref());
}
/// Executes the given function after the given duration of time has passed.
/// [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout).
#[cfg_attr(
debug_assertions,
instrument(level = "trace", skip_all, fields(duration = ?duration))
)]
pub fn set_timeout(cb: impl FnOnce() + 'static, duration: Duration) {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let cb = move || {
let _guard = span.enter();
cb();
};
}
}
let cb = Closure::once_into_js(Box::new(cb) as Box<dyn FnOnce()>);
_ = window().set_timeout_with_callback_and_timeout_and_arguments_0(
cb.as_ref().unchecked_ref(),
@@ -107,10 +143,24 @@ impl IntervalHandle {
/// Repeatedly calls the given function, with a delay of the given duration between calls.
/// See [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval).
#[cfg_attr(
debug_assertions,
instrument(level = "trace", skip_all, fields(duration = ?duration))
)]
pub fn set_interval(
cb: impl Fn() + 'static,
duration: Duration,
) -> Result<IntervalHandle, JsValue> {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let cb = move || {
let _guard = span.enter();
cb();
};
}
}
let cb = Closure::wrap(Box::new(cb) as Box<dyn Fn()>).into_js_value();
let handle = window()
.set_interval_with_callback_and_timeout_and_arguments_0(
@@ -121,10 +171,24 @@ pub fn set_interval(
}
/// Adds an event listener to the `Window`.
#[cfg_attr(
debug_assertions,
instrument(level = "trace", skip_all, fields(event_name = %event_name))
)]
pub fn window_event_listener(
event_name: &str,
cb: impl Fn(web_sys::Event) + 'static,
) {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
let cb = move |e| {
let _guard = span.enter();
cb(e);
};
}
}
if !is_server() {
let handler = Box::new(cb) as Box<dyn FnMut(web_sys::Event)>;

View File

@@ -90,7 +90,12 @@ where
element: el,
};
HtmlElement { cx, element }
HtmlElement {
cx,
element,
#[cfg(debug_assertions)]
span: ::tracing::Span::current()
}
}
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
@@ -192,6 +197,8 @@ cfg_if! {
/// Represents an HTML element.
#[derive(Clone)]
pub struct HtmlElement<El: ElementDescriptor> {
#[cfg(debug_assertions)]
pub(crate) span: ::tracing::Span,
pub(crate) cx: Scope,
pub(crate) element: El,
}
@@ -236,6 +243,8 @@ impl<El: ElementDescriptor + 'static> HtmlElement<El> {
Self {
cx,
element,
#[cfg(debug_assertions)]
span: ::tracing::Span::current()
}
} else {
Self {
@@ -272,6 +281,8 @@ impl<El: ElementDescriptor + 'static> HtmlElement<El> {
let Self {
cx,
element,
#[cfg(debug_assertions)]
span
} = self;
HtmlElement {
@@ -281,6 +292,8 @@ impl<El: ElementDescriptor + 'static> HtmlElement<El> {
element: element.as_ref().clone(),
is_void: element.is_void(),
},
#[cfg(debug_assertions)]
span
}
} else {
let Self {
@@ -571,10 +584,23 @@ impl<El: ElementDescriptor + 'static> HtmlElement<El> {
pub fn on<E: EventDescriptor + 'static>(
self,
event: E,
event_handler: impl FnMut(E::EventType) + 'static,
#[allow(unused_mut)] // used for tracing in debug
mut event_handler: impl FnMut(E::EventType) + 'static,
) -> Self {
#[cfg(all(target_arch = "wasm32", feature = "web"))]
{
cfg_if! {
if #[cfg(debug_assertions)] {
let span = self.span.clone();
let onspan = ::tracing::span!(
parent: &self.span,
::tracing::Level::TRACE,
"on",
event = %event.name()
);
let _onguard = onspan.enter();
}
}
let event_name = event.name();
if event.bubbles() {
@@ -683,9 +709,9 @@ impl<El: ElementDescriptor> IntoView for HtmlElement<El> {
let children = children;
if attrs.iter_mut().any(|(name, _)| name == "id") {
attrs.push(("leptos-hk".into(), format!("_{}", id).into()));
attrs.push(("leptos-hk".into(), format!("_{id}").into()));
} else {
attrs.push(("id".into(), format!("_{}", id).into()));
attrs.push(("id".into(), format!("_{id}").into()));
}
element.attrs = attrs;
@@ -865,6 +891,17 @@ macro_rules! generate_html_tags {
}
#[$meta]
#[cfg_attr(
debug_assertions,
instrument(
level = "trace",
name = "HtmlElement",
skip_all,
fields(
tag = %format!("<{}/>", stringify!($tag))
)
)
)]
pub fn $tag(cx: Scope) -> HtmlElement<[<$tag:camel $($trailing_)?>]> {
HtmlElement::new(cx, [<$tag:camel $($trailing_)?>]::default())
}

View File

@@ -3,9 +3,9 @@ use std::{cell::RefCell, fmt::Display};
#[cfg(all(target_arch = "wasm32", feature = "web"))]
use once_cell::unsync::Lazy as LazyCell;
/// We can tell if we start in hydration mode by checking to see if the
/// id "_0" is present in the DOM. If it is, we know we are hydrating from
/// the server, if not, we are starting off in CSR
// We can tell if we start in hydration mode by checking to see if the
// id "_0-0-0" is present in the DOM. If it is, we know we are hydrating from
// the server, if not, we are starting off in CSR
#[cfg(all(target_arch = "wasm32", feature = "web"))]
thread_local! {
static IS_HYDRATING: RefCell<LazyCell<bool>> = RefCell::new(LazyCell::new(|| {

View File

@@ -206,7 +206,12 @@ impl Element {
is_void: false,
};
HtmlElement { cx, element }
HtmlElement {
cx,
element,
#[cfg(debug_assertions)]
span: ::tracing::Span::current()
}
}
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
@@ -542,8 +547,19 @@ impl View {
pub fn on<E: ev::EventDescriptor + 'static>(
self,
event: E,
event_handler: impl FnMut(E::EventType) + 'static,
mut event_handler: impl FnMut(E::EventType) + 'static,
) -> Self {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
trace!("calling on() {}", event.name());
let span = ::tracing::Span::current();
let event_handler = move |e| {
let _guard = span.enter();
event_handler(e);
};
}
}
self.on_impl(event, Box::new(event_handler))
}

View File

@@ -45,7 +45,7 @@ macro_rules! debug_warn {
/// or via `println!()` (if not in the browser).
pub fn console_log(s: &str) {
if is_server() {
println!("{}", s);
println!("{s}");
} else {
web_sys::console::log_1(&JsValue::from_str(s));
}
@@ -55,7 +55,7 @@ pub fn console_log(s: &str) {
/// or via `println!()` (if not in the browser).
pub fn console_warn(s: &str) {
if is_server() {
eprintln!("{}", s);
eprintln!("{s}");
} else {
web_sys::console::warn_1(&JsValue::from_str(s));
}
@@ -65,7 +65,7 @@ pub fn console_warn(s: &str) {
/// or via `println!()` (if not in the browser).
pub fn console_error(s: &str) {
if is_server() {
eprintln!("{}", s);
eprintln!("{s}");
} else {
web_sys::console::warn_1(&JsValue::from_str(s));
}
@@ -77,7 +77,7 @@ pub fn console_debug_warn(s: &str) {
cfg_if! {
if #[cfg(debug_assertions)] {
if is_server() {
eprintln!("{}", s);
eprintln!("{s}");
} else {
web_sys::console::warn_1(&JsValue::from_str(s));
}

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_macro"
version = "0.1.0-beta"
version.workspace = true
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
@@ -22,15 +22,15 @@ quote = "1"
syn = { version = "1", features = ["full"] }
syn-rsx = "0.9"
uuid = { version = "1", features = ["v4"] }
leptos_dom = { path = "../leptos_dom", version = "0.1.0-beta" }
leptos_reactive = { path = "../leptos_reactive", version = "0.1.0-beta" }
leptos_server = { path = "../leptos_server", version = "0.1.0-beta" }
leptos_dom.workspace = true
leptos_reactive.workspace = true
leptos_server.workspace = true
lazy_static = "1.4"
[dev-dependencies]
log = "0.4"
typed-builder = "0.10"
leptos = { path = "../leptos" }
leptos.workspace = true
[features]
default = ["ssr"]

View File

@@ -105,11 +105,11 @@ mod struct_info {
builder_attr,
builder_name: syn::Ident::new(&builder_name, proc_macro2::Span::call_site()),
conversion_helper_trait_name: syn::Ident::new(
&format!("{}_Optional", builder_name),
&format!("{builder_name}_Optional"),
proc_macro2::Span::call_site(),
),
core: syn::Ident::new(
&format!("{}_core", builder_name),
&format!("{builder_name}_core"),
proc_macro2::Span::call_site(),
),
})
@@ -282,7 +282,7 @@ mod struct_info {
});
let reconstructing = self.included_fields().map(|f| f.name);
let &FieldInfo {
let FieldInfo {
name: ref field_name,
ty: ref field_type,
..
@@ -391,7 +391,7 @@ mod struct_info {
),
proc_macro2::Span::call_site(),
);
let repeated_fields_error_message = format!("Repeated field {}", field_name);
let repeated_fields_error_message = format!("Repeated field {field_name}");
Ok(quote! {
#[allow(dead_code, non_camel_case_types, missing_docs)]
@@ -513,7 +513,7 @@ mod struct_info {
),
proc_macro2::Span::call_site(),
);
let early_build_error_message = format!("Missing required field {}", field_name);
let early_build_error_message = format!("Missing required field {field_name}");
Ok(quote! {
#[doc(hidden)]
@@ -622,7 +622,7 @@ mod struct_info {
// I'd prefer “a” or “an” to “its”, but determining which is grammatically
// correct is roughly impossible.
let doc =
format!("Finalise the builder and create its [`{}`] instance", name);
format!("Finalise the builder and create its [`{name}`] instance");
quote!(#[doc = #doc])
}
}
@@ -718,7 +718,7 @@ mod struct_info {
}
_ => Err(Error::new_spanned(
&assign,
format!("Unknown parameter {:?}", name),
format!("Unknown parameter {name:?}"),
)),
}
}
@@ -732,7 +732,7 @@ mod struct_info {
}
_ => Err(Error::new_spanned(
&path,
format!("Unknown parameter {:?}", name),
format!("Unknown parameter {name:?}"),
)),
}
}
@@ -747,7 +747,7 @@ mod struct_info {
let call_func = quote!(#call_func);
Error::new_spanned(
&call.func,
format!("Illegal builder setting group {}", call_func),
format!("Illegal builder setting group {call_func}"),
)
})?;
match subsetting_name.as_str() {
@@ -759,7 +759,7 @@ mod struct_info {
}
_ => Err(Error::new_spanned(
&call.func,
format!("Illegal builder setting group name {}", subsetting_name),
format!("Illegal builder setting group name {subsetting_name}"),
)),
}
}
@@ -924,7 +924,7 @@ mod field_info {
let tokenized_code = TokenStream::from_str(&code.value())?;
self.default = Some(
syn::parse(tokenized_code.into())
.map_err(|e| Error::new_spanned(code, format!("{}", e)))?,
.map_err(|e| Error::new_spanned(code, format!("{e}")))?,
);
} else {
return Err(Error::new_spanned(assign.right, "Expected string"));
@@ -933,7 +933,7 @@ mod field_info {
}
_ => Err(Error::new_spanned(
&assign,
format!("Unknown parameter {:?}", name),
format!("Unknown parameter {name:?}"),
)),
}
}
@@ -950,7 +950,7 @@ mod field_info {
}
_ => Err(Error::new_spanned(
&path,
format!("Unknown parameter {:?}", name),
format!("Unknown parameter {name:?}"),
)),
}
}
@@ -965,7 +965,7 @@ mod field_info {
let call_func = quote!(#call_func);
Error::new_spanned(
&call.func,
format!("Illegal builder setting group {}", call_func),
format!("Illegal builder setting group {call_func}"),
)
})?;
match subsetting_name.as_ref() {
@@ -977,7 +977,7 @@ mod field_info {
}
_ => Err(Error::new_spanned(
&call.func,
format!("Illegal builder setting group name {}", subsetting_name),
format!("Illegal builder setting group name {subsetting_name}"),
)),
}
}
@@ -1047,7 +1047,7 @@ mod field_info {
}
_ => Err(Error::new_spanned(
&assign,
format!("Unknown parameter {:?}", name),
format!("Unknown parameter {name:?}"),
)),
}
}

View File

@@ -47,7 +47,7 @@ pub fn server_macro_impl(args: proc_macro::TokenStream, s: TokenStream2) -> Resu
use proc_macro::Span;
let span = Span::call_site();
#[cfg(not(target_os = "windows"))]
let url = format!("{}/{}", span.source_file().path().to_string_lossy(), fn_name_as_str).replace("/", "-");
let url = format!("{}/{}", span.source_file().path().to_string_lossy(), fn_name_as_str).replace('/', "-");
#[cfg(target_os = "windows")]
let url = format!("{}/{}", span.source_file().path().to_string_lossy(), fn_name_as_str).replace("\\", "-");
} else {

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_reactive"
version = "0.1.0-beta"
version.workspace = true
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"

View File

@@ -53,7 +53,7 @@ use std::fmt::Debug;
level = "trace",
skip_all,
fields(
scope = %format!("{:?}", cx.id),
scope = ?cx.id,
ty = %std::any::type_name::<T>()
)
)
@@ -107,7 +107,7 @@ where
level = "trace",
skip_all,
fields(
scope = %format!("{:?}", cx.id),
scope = ?cx.id,
ty = %std::any::type_name::<T>()
)
)
@@ -128,7 +128,7 @@ where
level = "trace",
skip_all,
fields(
scope = %format!("{:?}", cx.id),
scope = ?cx.id,
ty = %std::any::type_name::<T>()
)
)
@@ -172,9 +172,9 @@ where
level = "debug",
skip_all,
fields(
id = %format!("{:?}", id),
defined_at = %format!("{:?}", self.defined_at),
ty = %std::any::type_name::<T>()
id = ?id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
)]
@@ -220,7 +220,7 @@ impl EffectId {
level = "debug",
skip_all,
fields(
id = %format!("{:?}", self),
id = ?self,
)
)
)]

View File

@@ -60,7 +60,7 @@ use std::fmt::Debug;
level = "trace",
skip_all,
fields(
cx = %format!("{:?}", cx.id),
cx = ?cx.id,
)
)
)]
@@ -155,8 +155,8 @@ impl<T> UntrackedGettableSignal<T> for Memo<T> {
name = "Memo::get_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.0.id),
defined_at = %format!("{:?}", self.1),
id = ?self.0.id,
defined_at = %self.1,
ty = %std::any::type_name::<T>()
)
)
@@ -177,8 +177,8 @@ impl<T> UntrackedGettableSignal<T> for Memo<T> {
name = "Memo::with_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.0.id),
defined_at = %format!("{:?}", self.1),
id = ?self.0.id,
defined_at = %self.1,
ty = %std::any::type_name::<T>()
)
)
@@ -217,8 +217,8 @@ where
level = "trace",
skip_all,
fields(
id = %format!("{:?}", self.0.id),
defined_at = %format!("{:?}", self.1)
id = ?self.0.id,
defined_at = %self.1
)
)
)]
@@ -256,8 +256,8 @@ where
level = "trace",
skip_all,
fields(
id = %format!("{:?}", self.0.id),
defined_at = %format!("{:?}", self.1),
id = ?self.0.id,
defined_at = %self.1,
ty = %std::any::type_name::<T>()
)
)

View File

@@ -89,7 +89,7 @@ where
level = "trace",
skip_all,
fields(
scope = %format!("{:?}", cx.id),
scope = ?cx.id,
ty = %std::any::type_name::<T>(),
signal_ty = %std::any::type_name::<S>(),
)
@@ -208,7 +208,7 @@ where
level = "trace",
skip_all,
fields(
scope = %format!("{:?}", cx.id),
scope = ?cx.id,
ty = %std::any::type_name::<T>(),
signal_ty = %std::any::type_name::<S>(),
)

View File

@@ -51,7 +51,7 @@ use thiserror::Error;
level = "trace",
skip_all,
fields(
scope = %format!("{:?}", cx.id),
scope = ?cx.id,
ty = %std::any::type_name::<T>()
)
)
@@ -72,7 +72,7 @@ pub fn create_signal<T>(cx: Scope, value: T) -> (ReadSignal<T>, WriteSignal<T>)
level = "trace",
skip_all,
fields(
scope = %format!("{:?}", cx.id),
scope = ?cx.id,
)
)
)]
@@ -154,8 +154,8 @@ impl<T> UntrackedGettableSignal<T> for ReadSignal<T> {
name = "ReadSignal::get_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -174,8 +174,8 @@ impl<T> UntrackedGettableSignal<T> for ReadSignal<T> {
name = "ReadSignal::with_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -214,8 +214,8 @@ where
name = "ReadSignal::with()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -254,8 +254,8 @@ where
name = "ReadSignal::get()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -391,8 +391,8 @@ where
name = "WriteSignal::set_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -409,8 +409,8 @@ where
name = "WriteSignal::updated_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -426,8 +426,8 @@ where
name = "WriteSignal::update_returning_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -468,8 +468,8 @@ where
level = "trace",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -506,8 +506,8 @@ where
name = "WriteSignal::update_returning()"
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -542,8 +542,8 @@ where
name = "WriteSignal::set()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -691,8 +691,8 @@ impl<T> UntrackedGettableSignal<T> for RwSignal<T> {
name = "RwSignal::get_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -712,8 +712,8 @@ impl<T> UntrackedGettableSignal<T> for RwSignal<T> {
name = "RwSignal::with_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -731,8 +731,8 @@ impl<T> UntrackedSettableSignal<T> for RwSignal<T> {
name = "RwSignal::set_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -749,8 +749,8 @@ impl<T> UntrackedSettableSignal<T> for RwSignal<T> {
name = "RwSignal::update_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -766,8 +766,8 @@ impl<T> UntrackedSettableSignal<T> for RwSignal<T> {
name = "RwSignal::update_returning_untracked()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -807,8 +807,8 @@ where
name = "RwSignal::with()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -838,8 +838,8 @@ where
name = "RwSignal::get()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -875,8 +875,8 @@ where
name = "RwSignal::update()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -911,8 +911,8 @@ where
name = "RwSignal::update_returning()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -942,8 +942,8 @@ where
name = "RwSignal::set()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -975,8 +975,8 @@ where
name = "RwSignal::read_only()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -1013,8 +1013,8 @@ where
name = "RwSignal::write_only()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -1050,8 +1050,8 @@ where
name = "RwSignal::split()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -1084,8 +1084,8 @@ where
name = "RwSignal::to_stream()",
skip_all,
fields(
id = %format!("{:?}", self.id),
defined_at = %format!("{:?}", self.defined_at),
id = ?self.id,
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)

View File

@@ -1,5 +1,21 @@
use crate::{store_value, Memo, ReadSignal, RwSignal, Scope, StoredValue, UntrackedGettableSignal};
/// Helper trait for converting `Fn() -> T` closures into
/// [`Signal<T>`].
pub trait IntoSignal<T>: Sized {
/// Consumes `self`, returning a [`Signal<T>`].
fn derive_signal(self, cx: Scope) -> Signal<T>;
}
impl<F, T> IntoSignal<T> for F
where
F: Fn() -> T + 'static,
{
fn derive_signal(self, cx: Scope) -> Signal<T> {
Signal::derive(cx, self)
}
}
/// A wrapper for any kind of readable reactive signal: a [ReadSignal](crate::ReadSignal),
/// [Memo](crate::Memo), [RwSignal](crate::RwSignal), or derived signal closure.
///
@@ -109,7 +125,7 @@ where
level = "trace",
skip_all,
fields(
cx = %format!("{:?}", cx.id)
cx = ?cx.id
)
)
)]
@@ -163,7 +179,7 @@ where
level = "trace",
skip_all,
fields(
defined_at = %format!("{:?}", self.defined_at),
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -204,7 +220,7 @@ where
level = "trace",
skip_all,
fields(
defined_at = %format!("{:?}", self.defined_at),
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)
@@ -425,6 +441,18 @@ where
/// assert_eq!(above_3(&double_count), true);
/// # });
/// ```
#[cfg_attr(
debug_assertions,
instrument(
level = "trace",
name = "MaybeSignal::derive()",
skip_all,
fields(
cx = ?cx.id,
ty = %std::any::type_name::<T>()
)
)
)]
pub fn derive(cx: Scope, derived_signal: impl Fn() -> T + 'static) -> Self {
Self::Dynamic(Signal::derive(cx, derived_signal))
}
@@ -461,6 +489,15 @@ where
/// assert_eq!(static_value(), "Bob");
/// });
/// ```
#[cfg_attr(
debug_assertions,
instrument(
level = "trace",
name = "MaybeSignal::derive()",
skip_all,
fields(ty = %std::any::type_name::<T>())
)
)]
pub fn with<U>(&self, f: impl FnOnce(&T) -> U) -> U {
match &self {
Self::Static(value) => f(value),
@@ -492,6 +529,15 @@ where
/// assert_eq!(above_3(&static_value.into()), true);
/// # });
/// ```
#[cfg_attr(
debug_assertions,
instrument(
level = "trace",
name = "MaybeSignal::derive()",
skip_all,
fields(ty = %std::any::type_name::<T>())
)
)]
pub fn get(&self) -> T
where
T: Clone,

View File

@@ -1,5 +1,20 @@
use crate::{store_value, RwSignal, Scope, StoredValue, WriteSignal};
/// Helper trait for converting `Fn(T)` into [`SignalSetter<T>`].
pub trait IntoSignalSetter<T>: Sized {
/// Consumes `self`, returning [`SignalSetter<T>`].
fn mapped_signal_setter(self, cx: Scope) -> SignalSetter<T>;
}
impl<F, T> IntoSignalSetter<T> for F
where
F: Fn(T) + 'static,
{
fn mapped_signal_setter(self, cx: Scope) -> SignalSetter<T> {
SignalSetter::map(cx, self)
}
}
/// A wrapper for any kind of settable reactive signal: a [WriteSignal](crate::WriteSignal),
/// [RwSignal](crate::RwSignal), or closure that receives a value and sets a signal depending
/// on it.
@@ -92,7 +107,7 @@ where
level = "trace",
skip_all,
fields(
cx = %format!("{:?}", cx.id),
cx = ?cx.id,
)
)
)]
@@ -130,7 +145,7 @@ where
level = "trace",
skip_all,
fields(
defined_at = %format!("{:?}", self.defined_at),
defined_at = %self.defined_at,
ty = %std::any::type_name::<T>()
)
)

View File

@@ -1,6 +1,6 @@
[package]
name = "leptos_server"
version = "0.1.0-beta"
version.workspace = true
edition = "2021"
authors = ["Greg Johnston"]
license = "MIT"
@@ -8,8 +8,8 @@ repository = "https://github.com/gbj/leptos"
description = "RPC for the Leptos web framework."
[dependencies]
leptos_dom = { path = "../leptos_dom", default-features = false, version = "0.1.0-beta" }
leptos_reactive = { path = "../leptos_reactive", default-features = false, version = "0.1.0-beta" }
leptos_dom.workspace = true
leptos_reactive.workspace = true
form_urlencoded = "1"
gloo-net = "0.2"
lazy_static = "1"
@@ -26,7 +26,7 @@ proc-macro2 = "1.0.47"
ciborium = "0.2.0"
[dev-dependencies]
leptos = { path = "../leptos", default-features = false }
leptos.workspace = true
[features]
csr = [

View File

@@ -9,7 +9,7 @@ description = "Tools to set HTML metadata in the Leptos web framework."
[dependencies]
cfg-if = "1"
leptos = { path = "../leptos", version = "0.1.0-beta", default-features = false }
leptos.workspace = true
tracing = "0.1"
typed-builder = "0.11"
@@ -18,7 +18,7 @@ version = "0.3"
features = ["HtmlLinkElement", "HtmlMetaElement", "HtmlTitleElement"]
[features]
default = ["csr"]
default = []
csr = ["leptos/csr", "leptos/tracing"]
hydrate = ["leptos/hydrate", "leptos/tracing"]
ssr = ["leptos/ssr", "leptos/tracing"]

View File

@@ -80,10 +80,6 @@ pub(crate) struct MetaTagsContext {
impl MetaTagsContext {
#[cfg(feature = "ssr")]
pub fn as_string(&self) -> String {
println!(
"\n\nrendering {} elements to strings\n\n",
self.els.borrow().len()
);
self.els
.borrow()
.iter()

View File

@@ -8,7 +8,7 @@ repository = "https://github.com/gbj/leptos"
description = "Router for the Leptos web framework."
[dependencies]
leptos = { path = "../leptos", version = "0.1.0-beta", default-features = false }
leptos.workspace = true
cfg-if = "1"
common_macros = "0.1"
gloo-net = "0.2"
@@ -53,7 +53,7 @@ features = [
]
[features]
default = ["csr"]
default = []
csr = ["leptos/csr"]
hydrate = ["leptos/hydrate"]
ssr = ["leptos/ssr", "dep:url", "dep:regex"]

View File

@@ -118,7 +118,7 @@ where
Some(value) => match T::from_str(value) {
Ok(value) => Ok(Some(value)),
Err(e) => {
eprintln!("{}", e);
eprintln!("{e}");
Err(ParamsError::Params(Rc::new(e)))
}
},