import type { HttpResponse } from "@yaakapp-internal/models"; import type { ServerSentEvent } from "@yaakapp-internal/sse"; import classNames from "classnames"; import { Fragment, useMemo, useState } from "react"; import { useFormatText } from "../../hooks/useFormatText"; import { useResponseBodyEventSource } from "../../hooks/useResponseBodyEventSource"; import { isJSON } from "../../lib/contentType"; import { Button } from "../core/Button"; import type { EditorProps } from "../core/Editor/Editor"; import { Editor } from "../core/Editor/LazyEditor"; import { EventDetailHeader, EventViewer } from "../core/EventViewer"; import { EventViewerRow } from "../core/EventViewerRow"; import { Icon } from "../core/Icon"; import { InlineCode } from "../core/InlineCode"; import { HStack, VStack } from "../core/Stacks"; interface Props { response: HttpResponse; } export function EventStreamViewer({ response }: Props) { return ( ); } function ActualEventStreamViewer({ response }: Props) { const [showLarge, setShowLarge] = useState(false); const [showingLarge, setShowingLarge] = useState(false); const events = useResponseBodyEventSource(response); return ( String(index)} error={events.error ? String(events.error) : null} splitLayoutName="sse_events" defaultRatio={0.4} renderRow={({ event, index, isActive, onClick }) => ( } content={ {event.data.slice(0, 1000)} } /> )} renderDetail={({ event, index, onClose }) => ( )} /> ); } function EventDetail({ event, index, showLarge, showingLarge, setShowLarge, setShowingLarge, onClose, }: { event: ServerSentEvent; index: number; showLarge: boolean; showingLarge: boolean; setShowLarge: (v: boolean) => void; setShowingLarge: (v: boolean) => void; onClose: () => void; }) { const language = useMemo<"text" | "json">(() => { if (!event?.data) return "text"; return isJSON(event?.data) ? "json" : "text"; }, [event?.data]); return (
} onClose={onClose} /> {!showLarge && event.data.length > 1000 * 1000 ? ( Message previews larger than 1MB are hidden
) : ( )}
); } function FormattedEditor({ text, language }: { text: string; language: EditorProps["language"] }) { const formatted = useFormatText({ text, language, pretty: true }); if (formatted == null) return null; return ; } function EventLabels({ className, event, index, isActive, }: { event: ServerSentEvent; index: number; className?: string; isActive?: boolean; }) { return ( {event.id ?? index} {event.eventType && ( {event.eventType} )} ); }