@v5x/web is the browser workflow layer built on top of @v5x/serial. It owns Web Serial support detection, connection lifecycle, snapshot state, subscriptions, explicit refresh, and normalized errors.
@v5x/web/react, @v5x/web/svelte, or @v5x/web/solid when your app already uses that framework.
Web Serial requires a browser that implements the API and a secure context such as HTTPS or localhost. The permission prompt must come from a user gesture, so call connect() from a click handler or similar.
Concurrent connect() calls share the active attempt and resolve to the same success or failure result. A call made while disconnect() is in progress resolves to false.
When Web Serial is unavailable, snapshots use status === "unsupported" and expose a stable unavailableReason. See Errors for the complete unavailable reason list.
The two controller entries in snapshot.device.controllers intentionally have different charging guarantees. The primary controller’s isCharging value is always a boolean. The partner controller’s value is boolean | undefined: undefined means the V5 system-status response did not report its charging state, while false means it explicitly reported that the controller is not charging.
Refresh failures are treated as stale or lost connections. When refresh() fails, the client stops background refresh, disconnects or disposes the current device, clears the attached device reference, and publishes an error snapshot with a normalized refresh-error. To retry, call connect() again; the client creates a fresh device and restarts background refresh only after that connection succeeds. To dismiss the error without retrying, call disconnect() and the client returns to idle.
@v5x/web does not replace @v5x/serial; it builds a small application-state contract on top of the serial device API.