crabnebula-dev / devtools Goto Github PK
View Code? Open in Web Editor NEWInspect and Debug your Tauri applications in style 💃
Home Page: https://devtools.crabnebula.dev
License: Other
Inspect and Debug your Tauri applications in style 💃
Home Page: https://devtools.crabnebula.dev
License: Other
Chrome devtools protocol sit on top of JSON-RPC and leverage websocket.
We should review first what the pro and cons and security wise what's the real implication. (using json-rpc vs gRPC)
Using websocket would probably be a good thing to stream the data to the devtools, and would highly simplify the protocol.
Something like jsonrpcsee would probably make sense.
When using tauri 2.x, add devtools
crate will fail.
➜ rust git:(master) cargo add devtools
Updating `rsproxy-sparse` index
Adding devtools v0.2.4 to dependencies.
Updating `rsproxy-sparse` index
error: failed to select a version for `webkit2gtk-sys`.
... required by package `webkit2gtk v0.18.2`
... which satisfies dependency `webkit2gtk = "^0.18.2"` of package `tauri v1.5.3`
... which satisfies dependency `tauri = "^1.5.3"` of package `devtools v0.2.4`
... which satisfies dependency `devtools = "^0.2.4"` of package `accelerator v0.0.2-alpha.2 (/Users/wangxingbin/Developer/lark/accelerator/app/rust)`
versions that meet the requirements `^0.18` are: 0.18.0
the package `webkit2gtk-sys` links to the native library `web_kit2`, but it conflicts with a previous package which links to `web_kit2` as well:
package `webkit2gtk-sys v2.0.1`
... which satisfies dependency `ffi = "^2.0.1"` of package `webkit2gtk v2.0.1`
... which satisfies dependency `webkit2gtk = "=2.0.1"` of package `tauri v2.0.0-alpha.18`
... which satisfies dependency `tauri = "^2.0.0-alpha.18"` of package `accelerator v0.0.2-alpha.2 (/Users/wangxingbin/Developer/lark/accelerator/app/rust)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='webkit2gtk-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
failed to select a version for `webkit2gtk-sys` which could resolve this conflict
When a client is registered, chances are high there have been events that happened before the listener got attached.
We should be sending an initial update to the client that "catches them up" to the current state.
The sources tab has a size_hint
that is used by the sources tabs CodeView
to allocate a Uint8Array
of the correct size. At least that's the idea.
Since that query parameter is technically untrusted user input we must sanitize it and also add handling for when it's absent. Reallocating the buffer if it's too small or something.
on_events
on_enter
: Track when a span is entered.on_close
: Track when a span is closed.The subscriber won't buffer events forever, at some point it will run out of space and start discarding events. If we can't keep up with sending updates to the client we will loose data. This is an important data point that we should track.
Currently testing the Layer
is difficult bc the data is generated through tracing
macros, tracing-mock
seems promising here, but can it integrate with a custom layer?
Note: The overarching goal is to ensure WebSocket clients receive near-real-time updates, at user-defined intervals.
Note 2: tokio-console
Have a nice Aggregator
that we should take inspiration and simplify by giving them the right credits, of course. (from @CrabNejonas)
error log found when build for ios
Compiling devtools-core v0.3.0 (https://github.com/crabnebula-dev/devtools#cc63b18a)
error: could not find native static library `tauri-plugin-devtools`, perhaps an -L flag is missing?
error: could not compile `tauri-plugin-devtools` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
Error [tauri_cli_node] Failed to run `cargo build`: command ["cargo", "build", "--package", "app", "--manifest-path", "/Users/chenyizhou/MyProject/next-note/frontend/src-tauri/Cargo.toml", "--target", "aarch64-apple-ios", "--features", "tauri/rustls-tls", "--lib", "--no-default-features"] exited with code 101
ELIFECYCLE Command failed with exit code 1.
Command PhaseScriptExecution failed with a nonzero exit code
note: Run script build phase 'Build Rust Code' will be run during every build because the option to run the script phase "Based on dependency analysis" is unchecked. (in target 'app_iOS' from project 'app')
** BUILD FAILED **
i use
tauri = { version = "2.0.0-beta.13", features = [] }
tauri-plugin-devtools = { git = "https://github.com/crabnebula-dev/devtools" }
tauri-build = { version = "2.0.0-beta.9", features = [] }
Known to be normal for macos constructs.
The Broadcaster is the most complex part of the system and should therefore receive the most scrutiny, but testing is difficult since its input is derived from tracing
data (see #45). And while we can test the broadcaster under a variety of situations, we should find a way to test it under the most common of situations: processing input.
Currently, the UI is a website that will be hosted at debug.crabnebula.dev
(or similar) where it will attempt to make a connection to ws://localhost:PORT
where PORT
is the port that the local instrumented apps JSON-rpc server is listening on.
This works fine in Chrome and Firefox, but not in Safari (ofc sigh).
Judging by this webkit ticket it also seems like this is not going to be fixed anytime soon, even though it technically goes against the current W3C standard. It seems like the Safari team and higher management within apple treat this behaviour "as intended" likely so they can claim better security and privacy than other browsers.
In short: This situation will remain as-is for the foreseeable future.
So what do we do about it? We essentially have two options:
local.devtools.crabnebula.dev
) add that builtin SSL certificate to the local devices keychain and then we can connect via wss://
or https://
This means detecting Safari and prompting people to use a different browser. I spoke with @atila-crabnebula about this and we realised we don't have any data on this. So lets do some data science aye:
This chart shows a breakdown of the @tauri-apps/cli
installs by OS, taken from the downloads of each os-arch specific sub package published to npm (like this one). Here's a more detailed breakdown that also includes breaks this down by arch and variant:
Now, this data is probably skewed by all sorts of factors:
@tauri-apps/cli
is commonly used in CI, the large market share of linux can be explained by the many installs in GH action runners.I realised we also did a survey (results can be found here) that also included a question about OS the participants would want to develop for (if I remember correctly).
This indicates 18.8% of survey participants are interested in developing apps for macOS, which requires using macOS to develop.
Again, this data is also skewed in all sorts of ways (mostly age breakdown, survey participants were overwhelmingly early in their careers)
But taken together I think it is safe to assume that roughly 15-25 percent of our user base regularly develop for macOS.
Note
Big grain of salt: There is no 1:1 relationship between people using macOS and people using Safari.
At least for the primarily frontend-developer, interested in Tauri it is safe to assume they have a second browser at least installed
Regardless of how big the Safari market share actually is, for those that are primarily safari users this means in the worst case:
I hope this helps to illustrate how this impacts user velocity. Additionally, this would introduce a repeated slowdown for users if they don't want to set the new browser as their default: They would have to manually copy&paste the link every time.
I don't have much input to give on option 1, except that it just screams nightmare to me as it would boil down to calling a command like this:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/.localhost-ssl/localhost.crt
I would love input from our security experts here @tillmann-crabnebula @chip-crabnebula @felsweg-crabnebula
So based on this, what would be my recommendation?
Given our deadlines and the amount of features we want to ship, speed is paramount. Because of this I would recommend we just go with option 2 and not support Safari for the time being at least until we have decided how devtools shall be distributed in general at which point we should revisit this issue.
@atila-crabnebula and @david-crabnebula have indicated they agree with this direction.
From a streamlined development perspective, it might make more sense initially to generate and ship the .d.ts
alongside a schema definition. This allows the frontend team to decide how they want to structure their WebSocket client, which they might decide to open-source later on.
The Tauri log plugin is widely used, but cannot coexist with devtools--this panic error crashes the app on startup when both plugins are added:
error while running tauri application: PluginInitialization("log", "attempted to set a logger after the logging system was already initialized")
This can be worked around by only adding the devtools plugin in development and only adding the log plugin in production, like so:
let builder = tauri::Builder::default();
#[cfg(debug_assertions)]
let builder = builder.plugin(devtools::init());
#[cfg(not(debug_assertions))]
let builder = builder.plugin(
tauri_plugin_log::Builder::default()
# example log plugin config below
.targets([LogTarget::Stdout, LogTarget::LogDir])
.with_colors(ColoredLevelConfig::default())
.level_for("tauri", LevelFilter::Info)
.level(LevelFilter::Info)
.build(),
);
builder
.plugin(...) # other plugins
.invoke_handler(tauri::generate_handler![
... # handlers
])
... # other stuff
.run(tauri::generate_context!())
.expect("error while running tauri application");
But this doesn't account for any log statements made on the JS side, like this:
import { debug } from 'tauri-plugin-log-api';
debug('debug log entry');
Ideally there would be some way to seamlessly redirect log entries to devtools in development while retaining normal log plugin behavior in production.
Add settings view, should include:
Adding this for closer to launch. We need to:
The instrumented app is broadcasting new events to the clients every 800ms right now, which feels a bit high. We should find a good value for this that balances snappy feeling updates with the inherent increase is overhead from broadcasting more often.
As we prepare for the initial launch of our devtools, we need to consolidate and discuss the proposed features. Based on our internal discussions, the following features are currently being considered:
Like to the Devtools console, but tailored for Rust logs originating from Tauri and associated crates. The core functionality should revolve around logs_watch
and logs_unwatch
. These should be active ONLY when the logs viewer is present in the viewport.
Representative of call stacks, especially IPC, Tauri commands, etc. The primary goal here is to measure metrics such as busy time, idle time, the time taken by on_enter
, and on_exit
. As of now, the naming and full features set for this module are not yet finalized. A potential feature could be filtering by name, allowing users to input, say, "ipc", and view all related IPC events with timing.
For the initial release, this could be a straightforward JSON viewer designed to simplify the process of inspecting the Tauri configuration. Important features might include search capabilities, easy navigation, and a clean UI to enhance user experience.
This would be a visual tool providing insights into what's bundled within a Tauri app. Using a treemap, users can visualize various assets - images, JavaScript files, and more. The objective is to offer a comprehensive visual representation of the Tauri app, highlighting its structure and content.
Leveraging GitHub Actions for CI/CD on private repositories might incur costs. Considering the early stage of our project and the limited number of contributors, it might be prudent to defer this setup until post-initial release.
https://github.com/crabnebula-dev/devtools/security/dependabot
We have two. Can you find a way to clean them up for us @CrabNejonas
The initial plan was to add tracing
statements directly to Tauri, but allowing other projects to be compatible with devtools (e.g. dioxus, emp) would require us (or the project maintainer) to keep all tracing span and event names in-sync as well as the emitted data. Because I can foresee issues with the current implementation:
I think it would therefore make sense to create a small wrapper crate around the tracing statements like so:
tracing::debug_span!(
"request_handler",
);
one would write
inspector_probes::request_handler!(
cmd = message.command(),
kind = kind,
loc.line = line,
loc.col = col,
is_internal = false,
)
where the arguments would be statically validated. Note this would still need to be a macro to preserve file, module and crate origins correctly.
Transition to Polyform Shield. This change is the result of recent discussions and will be subject to future modifications, specifically concerning the subscriber and the whole plugin in the long run (after stabilization).
LICENSE
fileCargo.toml
(SPDX)If any errors happen, we just exit the devtools instead of handling the error gracefully as evidenced by
devtools/web-client/src/views/dashboard/layout.tsx
Lines 76 to 78 in 66aad8f
Instead, it would probably be better to show some more meaningful and actionable errors like "connection interrupted, click to retry" or something similar.
Moreover, there are a number of SolidJS related issues where the context goes missing? Not sure we should bailout of the entire app in this case.
Apparently right now the file system enumeration can index the whole drive on windows if you give a path like "/"
that's obviously not good so we should fix that.
We should only be able to enumerate files inside the apps project folder
The repo need to be cleaned and we SHOULD credit https://github.com/tokio-rs/console
As the code I see in this repo come directly from tokio console and isn't credited.
PS> Thanks @benjaminkadmin-crabnebula for switching the repo as Internal
MIT
-- make sure our licensing alignall
files that contains tokio-rs console
codeSimplify and standardize the initialization of the plugin and inspector protocol in alignment with the tracing subscriber's behavior.
layer
instead of the subscriber.
let layer = inspector_protocol::layer()
.with_max_level(LevelFilter::TRACE);
init
and try_init
methods for initializing the layer.layer
can be combined with other layers (Layered). This provides flexibility for developers to use the fmt
subscriber simultaneously or any other layers as desired.layer
. We could also leverage .into()
Example:
rust .plugin(layer.plugin())
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.