aboutsummaryrefslogtreecommitdiff
path: root/source/library/components/ResultViewer.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'source/library/components/ResultViewer.svelte')
-rw-r--r--source/library/components/ResultViewer.svelte51
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}