diff options
Diffstat (limited to 'source/library/components/ResultViewer.svelte')
| -rw-r--r-- | source/library/components/ResultViewer.svelte | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/source/library/components/ResultViewer.svelte b/source/library/components/ResultViewer.svelte index 083828d..d277ec8 100644 --- a/source/library/components/ResultViewer.svelte +++ b/source/library/components/ResultViewer.svelte @@ -2,14 +2,50 @@ import Editor from "./Editor.svelte"; import type { Extension } from "@codemirror/state"; import type { Snippet } from "svelte"; + import type { TabTiming } from "../state/session.svelte.ts"; type Props = { footer?: Snippet<[{ result: string }]>; + streamIntervals?: number[]; theme?: Extension; + timing?: TabTiming | null; value: string; }; - let { footer, theme, value }: Props = $props(); + let { + footer, + streamIntervals = [], + theme, + timing = null, + value + }: Props = $props(); + + function median(values: number[]): number { + if (values.length === 0) + return 0; + + const sorted = [...values].sort((a, b) => a - b); + const mid = Math.floor(sorted.length / 2); + + return sorted.length % 2 === 0 ? + (sorted[mid - 1] + sorted[mid]) / 2 : + sorted[mid]; + } + + let metadata = $derived.by(() => { + if (!timing) + return null; + + if (streamIntervals.length > 0) { + const medianMs = Math.round(median(streamIntervals)); + const messages = streamIntervals.length + 1; + return `→ ${messages} messages · median ${medianMs}ms`; + } + + const totalMs = Math.round(timing.endMs - timing.startMs); + const firstByteMs = Math.round(timing.firstByteMs - timing.startMs); + return `→ ${totalMs}ms · first byte ${firstByteMs}ms`; + }); function noop(_v: string) {} </script> @@ -17,7 +53,7 @@ <style lang="scss"> .result { display: grid; - grid-template-rows: auto 1fr auto; + grid-template-rows: auto 1fr auto auto; height: 100%; min-height: 0; } @@ -30,6 +66,14 @@ text-transform: uppercase; } + .metadata { + background: var(--graphiql-panel, #252526); + border-top: 1px solid var(--graphiql-border, #333); + color: var(--graphiql-muted, #858585); + font-size: 0.75rem; + padding: 0.25rem 0.75rem; + } + .footer { background: var(--graphiql-panel, #252526); border-top: 1px solid var(--graphiql-border, #333); @@ -41,6 +85,9 @@ <div class="result"> <div class="label">Response</div> <Editor language="json" onChange={noop} readOnly {theme} {value}/> + {#if metadata} + <div class="metadata">{metadata}</div> + {/if} {#if footer} <div class="footer">{@render footer({ result: value })}</div> {/if} |