githubnext/chopinPublic

Let's compose rich plans together

Serve the client from one origin, and stop trusting a proxy to relay upgrades

Vite's dev proxy accepted the browser's WebSocket upgrade, opened the upstream
connection, received the 101 — and never wrote it back downstream. The socket
hung open forever: the server counted the client as present while the browser
waited for a handshake that never came, leaving the editor locked read-only
with nothing to explain why.

The server now owns the single origin in both modes. It answers `/ws` itself
and either serves the built client or forwards everything else to a running
Vite, so development, production and a tunnel all present one host and port.
Hot reload talks straight to Vite's own port rather than being relayed, which
means nothing anywhere proxies a WebSocket. Browse localhost:8787.

Which mode is which is now stated rather than sniffed. Testing for a `dist`
directory would have quietly served stale files in development the moment
somebody ran a build.

The status the header showed was also wrong, and would have been wrong for any
transport. A connection began life already recording `connecting`, so its first
transition was swallowed and never announced. React mounts an effect, discards
it and mounts again; the discarded connection's `closed` was therefore the last
thing anyone said, and a replacement whose socket never opened left it standing
forever. A connection now has no state until it has one.
KCKrzysztof Cieslak authored
9a50e90Patch
Parent2890123
8 files changed+390-23
StackedSplit
apps/server/src/client.test.ts+151 −0
apps/server/src/client.ts+81 −0
apps/server/src/config.ts+11 −0
apps/server/src/main.ts+3 −14
apps/web/src/wire.test.ts+110 −0
apps/web/src/wire.ts+12 −2
apps/web/vite.config.ts+21 −6
package.json+1 −1