import type { HttpResponse } from '@yaakapp-internal/models'; import type { ServerSentEvent } from '@yaakapp-internal/sse'; import classNames from 'classnames'; import React, { Fragment, useMemo, useState } from 'react'; import { useFormatText } from '../../hooks/useFormatText'; import { useResponseBodyEventSource } from '../../hooks/useResponseBodyEventSource'; import { isJSON } from '../../lib/contentType'; import { AutoScroller } from '../core/AutoScroller'; import { Banner } from '../core/Banner'; import { Button } from '../core/Button'; import type { EditorProps } from '../core/Editor/Editor'; import { Editor } from '../core/Editor/Editor'; import { Icon } from '../core/Icon'; import { InlineCode } from '../core/InlineCode'; import { Separator } from '../core/Separator'; import { SplitLayout } from '../core/SplitLayout'; 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 [activeEventIndex, setActiveEventIndex] = useState(null); const events = useResponseBodyEventSource(response); const activeEvent = useMemo( () => (activeEventIndex == null ? null : events.data?.[activeEventIndex]), [activeEventIndex, events], ); const language = useMemo<'text' | 'json'>(() => { if (!activeEvent?.data) return 'text'; return isJSON(activeEvent?.data) ? 'json' : 'text'; }, [activeEvent?.data]); return ( ( {String(events.error)} ) } render={(event, i) => ( { if (i === activeEventIndex) setActiveEventIndex(null); else setActiveEventIndex(i); }} /> )} /> )} secondSlot={ activeEvent ? () => ( Message Received {!showLarge && activeEvent.data.length > 1000 * 1000 ? ( Message previews larger than 1MB are hidden { setShowingLarge(true); setTimeout(() => { setShowLarge(true); setShowingLarge(false); }, 500); }} isLoading={showingLarge} color="secondary" variant="border" size="xs" > Try Showing ) : ( )} ) : null } /> ); } function FormattedEditor({ text, language }: { text: string; language: EditorProps['language'] }) { const formatted = useFormatText({ text, language, pretty: true }); if (formatted == null) return null; return ; } function EventRow({ onClick, isActive, event, className, index, }: { onClick: () => void; isActive: boolean; event: ServerSentEvent; className?: string; index: number; }) { return ( {event.data.slice(0, 1000)} ); } function EventLabels({ className, event, index, isActive, }: { event: ServerSentEvent; index: number; className: string; isActive?: boolean; }) { return ( {event.id ?? index} {event.eventType && ( {event.eventType} )} ); }