Surfaces ↓
Time
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.
Requests
you ask, the daemon answers; await the tagged result and check .ok
get(): Promise<TypedRequestResult<TimeSnapshot, never>>
push form: onSnapshot (subscribe instead of awaiting)
Webapp asks for the current TimeSnapshot (wall clock + locale +
timezone). Most webapps don't need this - the daemon also pushes
Changed events on the same shape whenever the source updates.
const res = await client.time.get();
if (res.ok) {
console.log(res.response.time);
} type Result =
| { ok: true; response: TimeSnapshot }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; Events
the daemon pushes these unprompted; subscribing returns an unsubscribe function
onChanged(handler: (TimeSnapshot) => void): () => void
const off = client.time.onChanged((snapshot) => {
console.log(snapshot.time);
});
// call off() to unsubscribe Types
shapes referenced above, as the SDK types them
Wraps TimeInfo for the wire; used as both the time.get reply and
the Changed event payload.
type TimeSnapshot = {
time: TimeInfo;
}; Wall clock + locale snapshot. wall_clock_unix_s is the gateway's
(or iAP2 device's) claimed "now" in unix-epoch seconds - webapps
reading time should use the device clock if any but use this as the
trust anchor on first arrival.
Two zone-identification paths coexist: companion gateways send
tz_iana (an IANA zone identifier like America/Denver) while iAP2
DeviceTimeUpdate only exposes numeric utc_offset_minutes plus a
separate dst_offset_minutes. Webapps prefer tz_iana when present
and fall back to the offset pair.
type TimeInfo = {
tzIana?: string;
locale?: string;
wallClockUnixS?: number;
utcOffsetMinutes?: number;
dstOffsetMinutes?: number;
};