
beyond-text-3
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v18View latest version
A realtime chat app. Messages are stored in Val Town SQLite and delivered to clients via Server-Sent Events over a single long-lived HTTP connection per client. Optimized for mobile + desktop.
Rendering mermaid diagram...
- Client opens one SSE connection to
GET /api/stream?sinceId=N. - Server polls SQLite every ~1.5s for rows with
id > lastSentand pushes each new row as an SSEmessageevent (with the row id as the event id). - Server closes the stream after 5 minutes; the browser's
EventSourceautomatically reconnects and resumes fromLast-Event-ID. This keeps individual isolates from piling up while preserving delivery semantics. - Heartbeat comments are sent every 20s so intermediaries don't drop idle connections.
- POSTing a message only inserts into SQLite — the SSE stream delivers it, so there's a single source of truth and no dedup logic needed on the client.
index.ts ← Hono server + /api routes + SSE stream
database/db.ts ← SQLite schema + queries
shared/types.ts ← Message type shared by client & server
frontend/
index.html ← Shell (full-height, viewport-fit=cover for mobile)
index.tsx ← React entrypoint
components/
App.tsx ← Layout + status dot
MessageList.tsx ← Renders messages (no auto-scroll)
MessageInput.tsx ← Input + Send (no auto-focus)
hooks/
useMessages.ts ← Initial load + SSE subscription + send
- No auto-scroll, no auto-focus on the input — per spec.
- Mobile friendly:
100dvhlayout,font-size: 16pxon input to prevent iOS zoom-on-focus,overscroll-behavior: noneon body. - Rounded pill send button with disabled state when the input is empty.
- Messages never delete;
messages_v1table is append-only.