-
-
Notifications
You must be signed in to change notification settings - Fork 647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
structural graph #1378
Comments
I implement an example in examples/debugger, code in leptos_debugger. It doesn't feel good. principle: Create a node and collect node information. Finally, the dependency graph is generated. Signals are transformed and collected by feature(min_specialization) |
I think this is a great idea. All of the data needed to create a dependency graph can be found in the leptos/leptos_reactive/src/runtime.rs Lines 59 to 63 in c1c49ce
NodeId s, and each one is linked to both its parents and its children:
An identical structure exists for leptos/leptos_reactive/src/runtime.rs Lines 49 to 51 in c1c49ce
I'm not sure what kind of API you're looking for, but I'm happy to expose whatever is useful for debugging purposes. A PR with what you need would be totally welcome. |
I didn't make it clear that what the leptos_reactive Runtime provides is not what I need. I think the API provides component and element names, properties and children in real time. I'll probably end up providing a simple PR to discuss this by the end of the week. |
I see, I misread your initial post. You're looking for the component (and element) tree, not the reactive graph. It's worth taking a look at the existing
I created this by augmenting #[component]
pub fn MyComponent(cx: Scope) -> impl IntoView {
view! { cx,
<main>
<div>
<button on:click=move |_| {tracing::debug!("clicked button")}>
"Click"
</button>
</div>
</main>
}
} As you can see it traces the component tree but not the nesting of HTML elements, so as I said — more can be done if you want the complete tree. EDIT: I'm not super familiar with tracing but I assume it's possible to create a subscriber of some kind that hooks into this instrumentation in real time for your purposes. |
I'm not familiar with tracing. I need to investigate tracing. |
I looked at the tracking and had a few questions:
I feel that it is better not to use the tracing library to trace the component dependency graph. In the future, tracing can be used as an underlying library for leptos_debugger to provide a call stack for user-triggered events. Maybe I haven't thought about it enough. |
@jquesada2016 and @benwis, you both know more about Taking a look it seems to me like we've instrumented everything to add spans, but nothing emits any events. So, if a user logs an event you get a nice log (especially with However it's very easy to add these sorts of tracing events. If, for example, I go to #[cfg(any(debug_assertions, feature = "ssr"))]
tracing::event!(tracing::Level::TRACE, tag = stringify!([<$tag>]), "Creating element"); and use one of our examples with a tracing subscriber, I get a nice TRACE-level message every time an element is created.
Presumably events like this could be used for the debugging purposes being described here. What's not clear to me is whether we'd need to add all these tracing events manually, or whether some of what we've annotated with spans should really events (like getting or setting a signal), or whether it's possible for a subscriber to hook into "you're entering a new span now." I don't know |
Oh actually I think the answer is implementing the |
@gbj I think it'd be a good idea to approach this from a top-down perspective. If you know what the end goal should look like, it'd be much easier to audit the current API to see if something's missing. Perhaps adding some kind of proof-of-concept design in Figma to see what the leptos debugger would look like would go a long way. Nevertheless, simply having the tracing spans is enough, no events need to be emitted manually because events are already being emitted for every span entered/exited. Just that by default So, what would need to happen for something like this to be done at runtime, would be for us to create a custom tracing subscriber that can be added to the There is one fundamental problem with the current API that I can see, however. This is that components don't emit span enter/leave events unless the component is actually mounted/rendered. This means we'd be able to make tooling for showing a debug view of the app and signals, but only for components that are actually mounted, and would not be able to see the entire app's component tree. For example: view! { cx,
<Content>
{if signal() { view! { cx, <CompA /> } } else { view! { cx, <CompB /> } }}
</Content>
} We'd be able to see the abb structure like:
but would not be able to show:
|
Right, thanks. This pointed me in the right direction. @luoxiaozero Here are my steps to get started understanding the power of
use tracing::{field::debug, span, Subscriber};
use tracing_subscriber::{
prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt,
};
struct SpanTracingLayer {}
impl<S: Subscriber> tracing_subscriber::Layer<S> for SpanTracingLayer {
fn on_new_span(
&self,
attrs: &span::Attributes<'_>,
id: &span::Id,
ctx: tracing_subscriber::layer::Context<'_, S>,
) {
// this can be whatever you want... for now it just logs
// eventually it will be used to build up and modify some data structure
leptos::log!("on_new_span {attrs:#?}");
}
}
fn main() {
console_error_panic_hook::set_once();
tracing_subscriber::fmt()
// this level can be adjusted to filter out messages of different levels of importance
.with_max_level(tracing::Level::TRACE)
.without_time()
.with_file(true)
.with_line_number(true)
.with_target(false)
.with_writer(tracing_subscriber_wasm::MakeConsoleWriter::default())
.with_ansi(false)
.pretty()
.finish()
// added it here
.with(SpanTracingLayer {})
.init();
// note: I also renamed `view_fn` to `App` and made it a `#[component]` just so it gets logged
mount_to_body(App);
}
Now you can see every single instrumented call firing!
I'd be very happy to change anything in the tracing instrumentation we have to make it more useful for your purposes. But I think it should be a really good start — it achieves what I think you're trying to do, without adding additional code to the framework. |
TBH I need to change several things about tracing. Greg's example is good for CSR, but for SSR there's an issue with the spans getting disconnected inside some of the spawning methods, and there is far, far too much output at too high of a trace level. |
I don't think the DOM nodes are currently included as one of the tracing attributes but they probably could be, for example by adding the element as a field in the instrumentation for |
Okay, thank you. I already have an idea. |
I wrote a PR that tracks component properties. Look #1531. |
@luoxiaozero are you still working on this? |
@bicarlsen Currently, I have shelved it. If you want to do work on this, you can refer to https://github.com/luoxiaozero/leptos-devtools |
Can leptos add interface of component structural graph?
Used to provide basic capabilities for browser extension development.
The text was updated successfully, but these errors were encountered: