Hosted apps

Hosted apps

A static app reaches native APIs over a loopback socket. A deployed SSR app cannot: its server runs remotely, and the page loads from an https origin. The hosted bridge connects them.

The shape

The device process dials wss://<slug>.serve.pekoui.com/__peko__ as a provider. The page connects to the same endpoint as a consumer. A hub pairs them by device id and relays calls and events between them.

The endpoint is fixed at path /__peko__ on port 3000. A plain GET there answers 426 Upgrade Required rather than hanging.

What actually listens on 3000 is a small front proxy shipped with every deploy. It starts your framework's server on an internal port, reverse-proxies everything except /__peko__, and terminates the bridge WebSocket itself. Other upgrades, including your framework's HMR and your own WebSockets, are piped straight through.

The frames

The same five as the local bridge: auth, ready, call, reply, event, plus error. Nothing new to learn.

Tokens

A shipped app carries no developer credential. The platform provisions the app's own bridge credential on every peko deploy server and injects it as an environment secret. The app's backend reads it and mints short-lived tokens for its own devices.

For a development device, or for manual testing:

peko bridge token

Tokens are ES256, valid about fifteen minutes, and refreshed automatically by both halves.

At the edge, the token is verified before the request reaches your app, and a trusted identity is injected as headers. Only the CDN can reach the origin, so those headers can be relied on.

Operational notes

  • Keep handlers stateless per message. Device-to-task affinity is best effort.
  • The connection heartbeats about every thirty seconds to spot a half-open socket.
  • Back off on reconnect. WebSocket traffic is metered against the app's hosting credits, and a reconnect storm can trip the credit cutoff.
  • A native WebSocket client should persist and resend the load balancer's stickiness cookie across reconnects. The client SDK does; a hand-rolled native client currently does not.

bridgeStatus

peko.bridgeStatus tells the page which mode it is in: local for the loopback bridge, ok for a working hosted bridge, mint-failed when the token could not be obtained, and null in a plain browser with no bridge at all.