import { useState } from 'react' import { getServerAddress } from '@junwon/config' interface UseServerResponse { generatePage: ( pageSpec: string, outputFormat: 'html' | 'react' ) => AsyncGenerator error: Error | null } const createServer = () => { const serverAddress = getServerAddress() let lastRequestTime = 0 const streamResponse = async function* ( endpoint: string, pageSpec: string, outputFormat: 'html' | 'react' ): AsyncGenerator { try { const now = Date.now() const timeSinceLastRequest = now - lastRequestTime if (timeSinceLastRequest < 1000) { throw new Error('Rate Limit Exceeded: Wait 1 second.') } lastRequestTime = now const response = await fetch(`${serverAddress}/${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ page_spec: pageSpec, output_format: outputFormat }), }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const reader = response.body?.getReader() if (!reader) throw new Error('No reader available') const decoder = new TextDecoder() try { while (true) { const { done, value } = await reader.read() if (done) break const chunk = decoder.decode(value, { stream: true }) if (chunk) yield chunk } } finally { reader.releaseLock() } } catch (err) { throw err instanceof Error ? err : new Error('Error') } } return { generatePage: (pageSpec: string, outputFormat: 'html' | 'react') => streamResponse('generate_page', pageSpec, outputFormat), error: null, } } let server: UseServerResponse | null = null export function useServer(): UseServerResponse { const [serverInstance] = useState(() => { if (!server) { server = createServer() } return server }) return serverInstance }