Surfaces ↓
Geo
client.geo Daemon -> webapp location surface: the Position stream a watch
produces, plus replies to geo.watch and geo.getOnce.
Requests
you ask, the daemon answers; await the tagged result and check .ok
watch(GeoWatch): Promise<TypedRequestResult<GeoWatchReply, GeoErrorReply>>
push form: onWatchReply (subscribe instead of awaiting)
Bridge -> companion watch forward. The daemon aggregates webapp
watches and re-issues this with the most-demanding accuracy +
fastest interval. min_interval_ms = 0 lets the gateway pick.
const res = await client.geo.watch({ accuracy: 'coarse', minIntervalMs: 0 });
if (res.ok) {
console.log(res.response.token);
} else {
console.warn(res.kind, res.error);
} type Result =
| { ok: true; response: GeoWatchReply }
| { ok: false; kind: 'domain'; error: GeoErrorReply }
| { ok: false; kind: 'protocol'; error: WireError }; getOnce(GeoGetOnce): Promise<TypedRequestResult<GeoGetOnceReply, GeoErrorReply>>
push form: onGetOnceReply (subscribe instead of awaiting)
const res = await client.geo.getOnce({ accuracy: 'coarse' });
if (res.ok) {
console.log(res.response.position);
} else {
console.warn(res.kind, res.error);
} type Result =
| { ok: true; response: GeoGetOnceReply }
| { ok: false; kind: 'domain'; error: GeoErrorReply }
| { ok: false; kind: 'protocol'; error: WireError }; Commands
fire-and-forget; the promise resolves once the daemon has taken the message
unwatch(GeoUnwatch): Promise<void>
await client.geo.unwatch({ token: '...' }); Events
the daemon pushes these unprompted; subscribing returns an unsubscribe function
onPosition(handler: (Position) => void): () => void
const off = client.geo.onPosition((position) => {
console.log(position.lat);
});
// call off() to unsubscribe Types
shapes referenced above, as the SDK types them
One position fix from the gateway. accuracy_m is the 1-sigma
horizontal radius. speed_mps and heading_deg are populated when
the underlying source provides them (CLLocation on iOS does for moving
fixes; Android's FusedLocationProvider similar). ts_ms is the
gateway-provided fix timestamp, not the wire-arrival time.
type Position = {
lat: number;
lon: number;
altM?: number;
accuracyM: number;
speedMps?: number;
headingDeg?: number;
tsUnixS: number;
}; Bridge -> companion watch forward. The daemon aggregates webapp
watches and re-issues this with the most-demanding accuracy +
fastest interval. min_interval_ms = 0 lets the gateway pick.
type GeoWatch = {
accuracy: GeoAccuracy;
minIntervalMs: number;
}; Watch handle. Webapps pass the token back as
ClientToBridgeGeoMsg::Unwatch { token } to release the watch.
Tokens are scoped to the webapp's WS connection - the daemon
auto-releases on disconnect.
type GeoWatchReply = {
token: string;
}; type GeoErrorReply = {
error: GeoError;
}; type GeoGetOnce = {
accuracy: GeoAccuracy;
}; type GeoGetOnceReply = {
position: Position;
}; Stop a previously-issued watch. token is the value returned in
GeoWatchReply.token. The daemon refcounts watches across webapps;
the companion gets Unwatch only when the last token is released.
type GeoUnwatch = {
token: string;
}; Subscriber's accuracy preference. Coarse opts into the lower-power
city-block-grade fix on platforms that distinguish (iOS reduced
accuracy, Android PRIORITY_BALANCED_POWER_ACCURACY). The daemon
aggregates across subscribers and forwards the most-demanding to the
companion.
type GeoAccuracy = 'coarse' | 'fine'; type GeoError =
| 'permissionDenied' // The user denied location to the companion app, or the OS gate refuses (e.g. iOS Always/WhenInUse not granted).
| 'unavailable' // Companion is connected but cannot produce a fix (no GPS, airplane mode, indoors with no fallback).
| 'unknownToken' // The supplied subscription token is unknown to the daemon.;