bridgething
Surfaces ↓

Webapp SDK

A bridgething webapp is a single-page UI that runs full-screen in the Car Thing's chromium kiosk and reaches the on-device daemon through one typed client: @bridgething/client. This reference is generated from the daemon's wire types.

Start a project

Scaffold a webapp (React + Vite + Tailwind, this client preinstalled), then open it with your coding agent:

bun create bridgething my-app

Source and issues on GitHub.

Connect

Construct the client once and reuse it (a useMemo in React). The daemon is the sole peer; you never open sockets or address anything.

import { BridgethingClient } from '@bridgething/client';

const client = new BridgethingClient(); // auto-connects, auto-reconnects

The three call shapes

Every surface method is one of three shapes. Learn these and the whole SDK reads the same way.

Events

the daemon pushes; you subscribe. onXxx returns an unsubscribe function.

const off = client.player.onSnapshot(r => render(r.state));
off(); // stop listening

Requests

you ask, the daemon answers. Returns a tagged result; check .ok.

const res = await client.player.stateGet();
if (res.ok) render(res.response.state);

Commands

fire-and-forget. Resolves once the daemon has taken the message.

await client.player.skipNext();

Request results

A request never returns its payload directly and never throws. It resolves to a tagged result you narrow on ok. This is the TypedRequestResult<Response, Error> in every request's signature:

type TypedRequestResult<Response, Error> =
  | { ok: true; response: Response }
  | { ok: false; kind: 'domain'; error: Error }
  | { ok: false; kind: 'protocol'; error: WireError };
  • ok: the discriminant. true means success; response holds the reply.
  • response: the typed reply payload (the Response in the method's signature). Only present when ok.
  • kind: on failure, 'domain' (an expected, operation-specific failure, e.g. an asset that isn't found) or 'protocol' (the request could not be reached or dispatched).
  • error: the failure detail. Your operation's error type when kind is 'domain', a WireError when 'protocol'.

Every request also accepts an optional second argument { timeoutMs }.

The 'protocol' failure carries a WireError: the request was malformed, unsupported, or the handler threw.

type WireError =
  | { type: 'unsupported' }
  | { type: 'unimplemented' }
  | { type: 'malformed'; data: { reason: string } }
  | { type: 'handlerFailed'; data: { reason: string } };

Surfaces

19 surfaces on client.<name>

Asset 4 methods
client.asset

Daemon-side asset events.

Audio 12 methods
client.audio

Daemon -> webapp audio events: TTS lifecycle notifications and volume/mute changes.

Bluetooth 11 methods
client.bluetooth

Daemon -> webapp bluetooth surface: connection status/events, in-flight pairing feedback, and the reply to bluetooth.list.

Capabilities 2 methods
client.capabilities

Daemon -> webapp capabilities surface.

Config 3 methods
client.config

Daemon -> webapp config replies and events.

Forward 3 methods
client.forward
Geo 4 methods
client.geo

Daemon -> webapp location surface: the Position stream a watch produces, plus replies to geo.watch and geo.getOnce.

Hardware 5 methods
client.hardware

Daemon -> webapp hardware surface: ambient-light and backlight change events, plus the reply to hardware.stateGet.

Library 9 methods
client.library

Daemon -> webapp replies and events for the library surface.

Net 13 methods
client.net

Daemon -> webapp network surface: replies to fetch and ws.open, WebSocket frame/close/error events, and the Stream* event trio driven by net.stream.open.

Notifications 5 methods
client.notifications

Daemon -> webapp notification mirror.

Peer 1 methods
client.peer

Daemon -> webapp peer surface: a full snapshot of every known peer (paired, iAP2, and companion-gateway state), re-sent whenever any peer changes.

Phone 17 methods
client.phone

Daemon -> webapp telephony surface.

Player 17 methods
client.player

Daemon -> webapp player surface.

Store 3 methods
client.store
System 13 methods
client.system

Daemon -> webapp system events and replies.

Time 2 methods
client.time

Daemon -> webapp wall-clock surface: an initial snapshot at announce, Changed events on tz/locale/clock updates, and the reply to time.get.

Voice 6 methods
client.voice

Daemon -> webapp voice/NLU surface: mic state-change events and the reply to voice.stateGet.

Webapp 7 methods
client.webapp

Daemon -> webapp replies and events for the webapp-management surface.