import { createSignal, onCleanup, onMount, Show, For, createMemo } from "solid-js" import styles from "./share.module.css" import { type UIMessage } from "ai" import { createStore, reconcile } from "solid-js/store" type Status = "disconnected" | "connecting" | "connected" | "error" | "reconnecting" type SessionMessage = UIMessage<{ time: { created: number; completed?: number; }; sessionID: string; tool: Record; time: { start: number; end: number; }; }>; }> type SessionInfo = { title: string tokens?: { input?: number output?: number reasoning?: number } } function getStatusText(status: [Status, string?]): string { switch (status[0]) { case "connected": return "Connected" case "connecting": return "Connecting..." case "disconnected": return "Disconnected" case "reconnecting": return "Reconnecting..." case "error": return status[1] || "Error" default: return "Unknown" } } export default function Share(props: { api: string }) { let params = new URLSearchParams(document.location.search) const sessionId = params.get("id") const [store, setStore] = createStore<{ info?: SessionInfo messages: Record }>({ messages: {}, }) const messages = createMemo(() => Object.values(store.messages).toSorted((a, b) => a.id?.localeCompare(b.id))) const [connectionStatus, setConnectionStatus] = createSignal<[Status, string?]>(["disconnected", "Disconnected"]) onMount(() => { const apiUrl = props.api console.log("Mounting Share component with ID:", sessionId) console.log("API URL:", apiUrl) if (!sessionId) { console.error("Session ID not found in environment variables") setConnectionStatus(["error", "Session ID not found"]) return } if (!apiUrl) { console.error("API URL not found in environment variables") setConnectionStatus(["error", "API URL not found"]) return } let reconnectTimer: number | undefined let socket: WebSocket | null = null // Function to create and set up WebSocket with auto-reconnect const setupWebSocket = () => { // Close any existing connection if (socket) { socket.close() } setConnectionStatus(["connecting"]) // Always use secure WebSocket protocol (wss) const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://") const wsUrl = `${wsBaseUrl}/share_poll?id=${sessionId}` console.log("Connecting to WebSocket URL:", wsUrl) // Create WebSocket connection socket = new WebSocket(wsUrl) // Handle connection opening socket.onopen = () => { setConnectionStatus(["connected"]) console.log("WebSocket connection established") } // Handle incoming messages socket.onmessage = (event) => { console.log("WebSocket message received") try { const data = JSON.parse(event.data) const [root, type, ...splits] = data.key.split("/") if (root !== "session") return if (type === "info") { setStore("info", reconcile(data.content)) return } if (type === "message") { const [, messageID] = splits setStore("messages", messageID, reconcile(data.content)) } } catch (error) { console.error("Error parsing WebSocket message:", error) } } // Handle errors socket.onerror = (error) => { console.error("WebSocket error:", error) setConnectionStatus(["error", "Connection failed"]) } // Handle connection close and reconnection socket.onclose = (event) => { console.log(`WebSocket closed: ${event.code} ${event.reason}`) setConnectionStatus(["reconnecting"]) // Try to reconnect after 2 seconds clearTimeout(reconnectTimer) reconnectTimer = window.setTimeout( setupWebSocket, 2000, ) as unknown as number } } // Initial connection setupWebSocket() // Clean up on component unmount onCleanup(() => { console.log("Cleaning up WebSocket connection") if (socket) { socket.close() } clearTimeout(reconnectTimer) }) }) return (

{store.info?.title}

{getStatusText(connectionStatus())}

  • Input Tokens {store.info?.tokens?.input ? {store.info?.tokens?.input} : }
  • Output Tokens {store.info?.tokens?.output ? {store.info?.tokens?.output} : }
  • Reasoning Tokens {store.info?.tokens?.reasoning ? {store.info?.tokens?.reasoning} : }
0} fallback={

Waiting for messages...

} >
    {(msg) => (
  • Key: {msg.id}
    {JSON.stringify(msg, null, 2)}
  • )}
) }