-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(spans-waterfall): add event spans
- Loading branch information
1 parent
06ec98f
commit 8980e29
Showing
13 changed files
with
386 additions
and
141 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { For, Show } from "solid-js"; | ||
import { useMonitor } from "~/lib/connection/monitor"; | ||
import { formatSpansForUi } from "~/lib/span/formatSpansForUi"; | ||
import { useSearchParams } from "@solidjs/router"; | ||
import { processFieldValue } from "~/lib/span/processFieldValue"; | ||
import { recursivelyFindSpanById } from "~/lib/span/recursivelyFindSpanById"; | ||
import { getEventPayload } from "~/lib/span/getEventPayload"; | ||
|
||
export function EventSpanDetail() { | ||
const [searchParams] = useSearchParams(); | ||
const { monitorData } = useMonitor(); | ||
const spanId = () => BigInt(searchParams.span); | ||
const span = () => | ||
formatSpansForUi({ | ||
spans: [recursivelyFindSpanById(monitorData.spans, spanId())!], | ||
metadata: monitorData.metadata, | ||
})[0]; | ||
console.log(span()); | ||
|
||
const payload = () => | ||
getEventPayload({ | ||
metadata: monitorData.metadata, | ||
rootSpan: recursivelyFindSpanById(monitorData.spans, spanId())!, | ||
})("window::emit")?.fields.map((f) => processFieldValue(f.payload))[0]; | ||
|
||
return ( | ||
<div class="h-full overflow-auto grid gap-4 content-start border-l border-gray-800"> | ||
<div class="pt-4 px-4"> | ||
<h2 class="text-2xl">{span?.name ?? "-"}</h2> | ||
</div> | ||
<table> | ||
<tbody> | ||
<For each={span().children ?? []}> | ||
{(span) => { | ||
return ( | ||
<tr class="even:bg-[#ffffff09] cursor-pointer hover:bg-[#ffffff05] even:hover:bg-[#ffffff10]"> | ||
<td class="py-1 px-4">{span.name}</td> | ||
<td class="py-1 px-4 relative w-[60%]"> | ||
<div class="relative w-[90%]"> | ||
<div class="bg-gray-800 w-full absolute rounded-sm h-2" /> | ||
<div class="relative h-2" style={span.waterfall}> | ||
{/* Slices is "time slices" as in multiple entry points to a given span */} | ||
<For each={span.slices}> | ||
{(slice) => ( | ||
<div | ||
class="absolute bg-teal-500 top-0 left-0 h-full" | ||
style={slice} | ||
/> | ||
)} | ||
</For> | ||
</div> | ||
</div> | ||
</td> | ||
</tr> | ||
); | ||
}} | ||
</For> | ||
</tbody> | ||
</table> | ||
<div class="grid gap-2"> | ||
<h2 class="text-xl p-4">Payload</h2> | ||
<table> | ||
<tbody> | ||
<Show when={payload()}> | ||
{(payload) => { | ||
return ( | ||
<p class="py-1 px-4"> | ||
{typeof payload() === "object" | ||
? JSON.stringify(payload()) | ||
: String(payload())} | ||
</p> | ||
); | ||
}} | ||
</Show> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { For, createResource, Show } from "solid-js"; | ||
import { useMonitor } from "~/lib/connection/monitor"; | ||
import { formatSpansForUi } from "~/lib/span/formatSpansForUi"; | ||
import { getIpcRequestValues } from "~/lib/span/getIpcRequestValue"; | ||
import { getHighlightedCode } from "~/lib/sources/code-highlight"; | ||
import { useSearchParams } from "@solidjs/router"; | ||
import { processFieldValue } from "~/lib/span/processFieldValue"; | ||
|
||
export function IpcSpanDetail() { | ||
const [searchParams] = useSearchParams(); | ||
const { monitorData } = useMonitor(); | ||
const spanId = () => BigInt(searchParams.span); | ||
const span = () => | ||
formatSpansForUi({ | ||
spans: monitorData.spans.filter((s) => s.id === spanId()), | ||
metadata: monitorData.metadata, | ||
})[0]; | ||
|
||
const responseCode = () => { | ||
const field = getIpcRequestValues({ | ||
metadata: monitorData.metadata, | ||
rootSpan: monitorData.spans.find((s) => s.id === spanId())!, | ||
})("ipc::request::response")?.fields[0]?.response; | ||
return field ? processFieldValue(field) : null; | ||
}; | ||
|
||
const args = () => | ||
getIpcRequestValues({ | ||
metadata: monitorData.metadata, | ||
rootSpan: monitorData.spans.find((s) => s.id === spanId())!, | ||
})("ipc::request")!.fields.map((f) => processFieldValue(f.request)); | ||
|
||
const [responseHtml] = createResource( | ||
() => [responseCode()] as const, | ||
async ([code]) => { | ||
return code === null | ||
? null | ||
: (await getHighlightedCode({ lang: "rust" }))(code).replace( | ||
/\\n/gim, // Turn escaped newlines into actual newlines | ||
"\n" | ||
); | ||
} | ||
); | ||
|
||
return ( | ||
<div class="h-full overflow-auto grid gap-4 content-start border-l border-gray-800"> | ||
<div class="pt-4 px-4"> | ||
<h2 class="text-2xl">{span?.name ?? "-"}</h2> | ||
</div> | ||
<table> | ||
<tbody> | ||
<For each={span().children ?? []}> | ||
{(span) => { | ||
return ( | ||
<tr class="even:bg-[#ffffff09] cursor-pointer hover:bg-[#ffffff05] even:hover:bg-[#ffffff10]"> | ||
<td class="py-1 px-4">{span.name}</td> | ||
<td class="py-1 px-4 relative w-[60%]"> | ||
<div class="relative w-[90%]"> | ||
<div class="bg-gray-800 w-full absolute rounded-sm h-2" /> | ||
<div class="relative h-2" style={span.waterfall}> | ||
{/* Slices is "time slices" as in multiple entry points to a given span */} | ||
<For each={span.slices}> | ||
{(slice) => ( | ||
<div | ||
class="absolute bg-teal-500 top-0 left-0 h-full" | ||
style={slice} | ||
/> | ||
)} | ||
</For> | ||
</div> | ||
</div> | ||
</td> | ||
</tr> | ||
); | ||
}} | ||
</For> | ||
</tbody> | ||
</table> | ||
<div class="grid gap-2"> | ||
<h2 class="text-xl p-4">Inputs</h2> | ||
<table> | ||
<tbody> | ||
<For each={args()}> | ||
{(arg) => { | ||
return ( | ||
<For each={Object.entries(JSON.parse(arg))}> | ||
{([k, v]) => ( | ||
<Show | ||
when={ | ||
![ | ||
"cmd", | ||
"callback", | ||
"error", | ||
"__tauriModule", | ||
].includes(k) | ||
} | ||
> | ||
<tr class="even:bg-[#ffffff09]"> | ||
<td class="py-1 px-4 font-bold">{k}</td> | ||
<td class="py-1 px-4"> | ||
{typeof v === "object" | ||
? JSON.stringify(v) | ||
: String(v)} | ||
</td> | ||
</tr> | ||
</Show> | ||
)} | ||
</For> | ||
); | ||
}} | ||
</For> | ||
</tbody> | ||
</table> | ||
</div> | ||
<Show when={responseHtml()}> | ||
{(html) => ( | ||
<div class="grid gap-2"> | ||
<h2 class="text-xl p-4">Response</h2> | ||
<pre class="bg-black rounded max-w-full overflow-auto"> | ||
<code | ||
// eslint-disable-next-line solid/no-innerhtml | ||
innerHTML={html()} | ||
/> | ||
</pre> | ||
</div> | ||
)} | ||
</Show> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.