A reload of a weeks-old session replayed the whole record before the first pixel, and every reconnect reset the mirror and replayed it again. The stream now names each frame's seq and the client keeps it, so a retry sends since=<seq> and receives only the gap, and the mirror is left alone: its items are still true. A first open with no cursor gets the tail, cut to a turn boundary, which paints the latest conversation at once. The turns above it come from the history route, one whole turn per page, fetched when the reader nears the top or when the transcript is too short to fill the screen; a page folds through the same reducer as the live stream and joins above, and the scroll position moves down by the page's height so the reader keeps their place. A reset comment (the record no longer holds the cursor) drops the mirror; the tail that follows rebuilds it. The dev proxy rebuilt the upstream URL from the pathname alone, so since and before never reached the daemon under nuxt dev: every resume was a full replay and every history page was the tail. It forwards the query string now.
25 lines
1.2 KiB
TypeScript
25 lines
1.2 KiB
TypeScript
// Dev-only same-origin proxy: forwards the claw's routes to a locally
|
|
// running daemon (`clawUpstream`, NUXT_CLAW_UPSTREAM to override) so
|
|
// the browser sees one origin and CORS never enters the picture.
|
|
//
|
|
// Why not `nitro.devProxy`: its httpxy pass never delivers responses to
|
|
// bodyless GETs (observed against nitro 2.13), which is exactly the
|
|
// shape of /healthz and /v1/sessions. `proxyRequest` is the same
|
|
// primitive nitro's route-rule proxy uses.
|
|
//
|
|
// The built bundle is static — with `import.meta.dev` false this falls
|
|
// through and the request 404s against the static output; in a real
|
|
// deployment the ingress owns /v1 and /healthz routing (README.md).
|
|
import { proxyRequest } from 'h3'
|
|
|
|
export default defineEventHandler((event) => {
|
|
if (!import.meta.dev) return
|
|
// The query string rides along: `since` on the event stream and
|
|
// `before`/`limit` on the history pages are the whole protocol, and a
|
|
// proxy that dropped them would quietly serve the tail to every
|
|
// request.
|
|
const { pathname, search } = getRequestURL(event)
|
|
if (pathname !== '/healthz' && !pathname.startsWith('/v1/')) return
|
|
return proxyRequest(event, useRuntimeConfig(event).clawUpstream + pathname + search)
|
|
})
|