Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion devtools/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ use futures::{FutureExt, Stream, TryStreamExt};
use std::net::SocketAddr;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use tauri::http::header::HeaderValue;
use tauri::{AppHandle, Runtime};
use tauri_devtools_wire_format as wire;
use tauri_devtools_wire_format::instrument;
use tauri_devtools_wire_format::instrument::instrument_server::InstrumentServer;
use tauri_devtools_wire_format::instrument::{instrument_server, InstrumentRequest};
use tauri_devtools_wire_format::meta::metadata_server::MetadataServer;
use tauri_devtools_wire_format::meta::{metadata_server, AppMetadata, AppMetadataRequest};
use tauri_devtools_wire_format::meta::{
metadata_server, AppMetadata, AppMetadataRequest, InstrumentationMetadata,
InstrumentationMetadataRequest,
};
use tauri_devtools_wire_format::sources::sources_server::SourcesServer;
use tauri_devtools_wire_format::sources::{Chunk, Entry, EntryRequest, FileType};
use tauri_devtools_wire_format::tauri::tauri_server::TauriServer;
Expand Down Expand Up @@ -65,12 +69,14 @@ struct SourcesService<R: Runtime> {

struct MetaService<R: Runtime> {
app_handle: AppHandle<R>,
publish_interval: Duration,
}

impl<R: Runtime> Server<R> {
pub fn new(
cmd_tx: mpsc::Sender<Command>,
app_handle: AppHandle<R>,
publish_interval: Duration,
metrics: Arc<RwLock<Metrics>>,
) -> Self {
let (mut health_reporter, health_service) = tonic_health::server::health_reporter();
Expand All @@ -95,6 +101,7 @@ impl<R: Runtime> Server<R> {
}, // the TauriServer doesn't need a health_reporter. It can never fail.
meta: MetaService {
app_handle: app_handle.clone(),
publish_interval,
},
sources: SourcesService { app_handle },
health: unsafe { std::mem::transmute(health_service) },
Expand Down Expand Up @@ -392,6 +399,21 @@ impl<R: Runtime> metadata_server::Metadata for MetaService<R> {

Ok(Response::new(meta))
}

async fn get_instrumentation_metadata(
&self,
_req: Request<InstrumentationMetadataRequest>,
) -> Result<Response<InstrumentationMetadata>, Status> {
let duration = prost_types::Duration {
seconds: self.publish_interval.as_secs() as i64,
nanos: self.publish_interval.subsec_nanos() as i32,
};

Ok(Response::new(InstrumentationMetadata {
version: env!("CARGO_PKG_VERSION").to_string(),
publish_interval: Some(duration),
}))
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion devtools/src/tauri_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub(crate) fn init<R: Runtime>(
let m = metrics.clone();
tauri::plugin::Builder::new("probe")
.setup(move |app_handle| {
let server = Server::new(cmd_tx, app_handle.clone(), m);
let server = Server::new(cmd_tx, app_handle.clone(), publish_interval, m);

// spawn the server and aggregator in a separate thread
// so we don't interfere with the application we're trying to instrument
Expand Down
2 changes: 2 additions & 0 deletions web-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
},
"dependencies": {
"@crabnebula/file-icons": "^0.1.0",
"@iarna/toml": "^2.2.5",
"@kobalte/core": "^0.11.2",
"@kobalte/tailwindcss": "^0.9.0",
"@protobuf-ts/grpcweb-transport": "^2.9.1",
"@protobuf-ts/plugin": "^2.9.1",
"@protobuf-ts/runtime": "^2.9.1",
Expand Down
18 changes: 18 additions & 0 deletions web-client/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions web-client/src/components/autoscroll-pane.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Accessor, JSX, createEffect, on } from "solid-js";
import { Accessor, JSXElement, createEffect, on } from "solid-js";

function scrollEnd(ref?: HTMLElement, smooth?: boolean) {
ref?.scroll({
Expand All @@ -14,7 +14,7 @@ function scrollEnd(ref?: HTMLElement, smooth?: boolean) {
type AutoScrollPaneProps = {
dataStream: unknown;
shouldAutoScroll: Accessor<boolean>;
children: JSX.Element;
children: JSXElement;
};

export function AutoscrollPane(props: AutoScrollPaneProps) {
Expand Down
8 changes: 4 additions & 4 deletions web-client/src/components/boot-time.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Show } from "solid-js";
import { useMonitor } from "~/lib/connection/monitor";
import { Loader } from "./loader";
import { useMonitor } from "~/context/monitor-provider";

export function BootTime() {
const { monitorData } = useMonitor();

return (
<Show when={monitorData.perfElapsed} fallback={"Waiting for data..."}>
<Show when={monitorData.perfElapsed} fallback={<Loader />}>
{(e) => (
<section>
<strong>Loading time: </strong>
<span class="font-mono">
{Number(e().seconds) * 1000 + e().nanos / 1e6}ms
{(Number(e().seconds) * 1000 + e().nanos / 1e6).toFixed(2)}ms
</span>
</section>
)}
Expand Down
15 changes: 9 additions & 6 deletions web-client/src/components/disconnect-button.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { Button } from "@kobalte/core";
import { useNavigate } from "@solidjs/router";
import { useConnection } from "~/context/connection-provider";

type DisconnectProps = {
closeSession: () => void;
};

export function DisconnectButton(props: DisconnectProps) {
export function DisconnectButton() {
const { connectionStore } = useConnection();
const goto = useNavigate();
return (
<Button.Root
type="button"
id="close"
class="border-gray-700 border rounded-md p-1 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500"
onClick={props.closeSession}
onClick={() => {
connectionStore.abortController.abort();
goto("/");
}}
>
<span class="sr-only">Close connection</span>
<svg
Expand Down
53 changes: 53 additions & 0 deletions web-client/src/components/error-dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { AlertDialog } from "@kobalte/core";
import { JSXElement, Show, mergeProps } from "solid-js";

type Props = {
title?: JSXElement;
children: JSXElement;
dismissible?: boolean;
};

export function ErrorDialog(p: Props) {
const props = mergeProps({ title: "Alert" }, p);
const dismissible = () => props.dismissible ?? true;

return (
<AlertDialog.Root defaultOpen modal preventScroll>
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion*/}
<AlertDialog.Portal mount={document.getElementById("app")!}>
<AlertDialog.Overlay class="fixed h-screen w-screen grid place-items-center backdrop-blur-md z-50 top-0 left-0" />
<div class="fixed inset-0 z-50 flex items-center justify-center text-xl">
<AlertDialog.Content class="z-50 text-4xl max-w-prose md:max-w-96 border border-neutral-800 rounded-lg p-10 bg-navy-700 bg-opacity-80 shadow-lg shadow-navy-600 kb-expanded:animate-content-show kb-disabled:animate-content-hide">
<div class="flex items-baseline justify-between mb-3">
<Show when={props.title}>{props.title}</Show>
</div>
<AlertDialog.Description class="text-base text-neutral-300">
{props.children}
</AlertDialog.Description>
<div class="pt-8 flex gap-10 justify-center">
<AlertDialog.CloseButton
class="border border-neutral-400 hover:bg-neutral-800 hover:border-neutral-100 text-white text-lg py-2 px-4 rounded focus:outline-dashed focus:outline-white focus:outline-offset-2"
onClick={() => {
window.location.reload();
}}
>
Reload route
</AlertDialog.CloseButton>
<Show when={dismissible()}>
<AlertDialog.CloseButton class="border border-neutral-400 hover:bg-neutral-800 hover:border-neutral-100 text-white text-lg py-2 px-4 rounded focus:outline-dashed focus:outline-white focus:outline-offset-2">
Dismiss
</AlertDialog.CloseButton>
</Show>
<a
href="/"
class="bg-red-400 border border-red-400 hover:bg-red-700 hover:border-red-900 text-white text-lg py-2 px-4 rounded focus:outline-dashed focus:outline-white focus:outline-offset-2"
>
Reset App
</a>
</div>
</AlertDialog.Content>
</div>
</AlertDialog.Portal>
</AlertDialog.Root>
);
}
68 changes: 68 additions & 0 deletions web-client/src/components/error-root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as pkg from "~/../package.json";

type Props = {
error: unknown;
};

export function ErrorRoot(props: Props) {
return (
<>
<div class="surf-container">
<img class="bg-surface static" src="/bg.jpeg" aria-hidden />
</div>
<div class="p-28 grid grid-rows-[auto_1fr_auto] gap-5 h-screen text-neutral-400 ">
<header>
<h1 class="text-red-400 font-semibold text-6xl">
Irrecoverable Error
</h1>
<div class="text-3xl pt-8">
<p>Something terrible happened.</p>
<p>The log is on the way and we'll work on it!</p>
</div>
</header>
<article class="flex flex-col justify-evenly">
<div class="p-5 border-2 border-slate-800 rounded-lg font-mono">
<h2 class="text-4xl relative -top-12">System log</h2>
<pre class="text-2xl">
{props.error?.toString() || String(props.error)}
</pre>
<ul class="pt-12">
<li>App version: {pkg.version}</li>
<li>Browser: {window.navigator.userAgent}</li>
</ul>
</div>
<div class="flex gap-10">
<a
href="/"
class="border border-red-400 hover:bg-red-700 hover:border-red-900 text-white text-lg py-2 px-4 rounded focus:outline-dashed focus:outline-white focus:outline-offset-2 focus:outline-1"
>
Reset App
</a>
<button
onClick={() => {
window.location.reload();
}}
class="border border-neutral-400 hover:bg-neutral-800 hover:border-neutral-100 text-white text-lg py-2 px-4 rounded focus:outline-dashed focus:outline-white focus:outline-offset-2"
>
Reload Route
</button>
</div>
</article>
<aside>
<p class="text-3xl">
Feel free to reach us at the{" "}
<a
href="https://discord.gg/tauri"
rel="noreferrer noopener"
target="_blank"
class="text-white focus:outline-none focus:underline focus:decoration-dotted focus:underline-offset-2"
>
Tauri Discord: #CrabNebula
</a>
.
</p>
</aside>
</div>
</>
);
}
Loading