miranda-engine / client-apps /web /src /lib /ace /spatialSyncer.ts
hunt
WO-5 T2: browser client for miranda-transport, verified against real Rust bytes
618e57d
Raw History Blame Contribute Delete
2.44 kB
import type { BusEvent, MediaClockSnapshot, PresenceStage } from "@/lib/stageMachine/types";
let seq = 0;
export function createBusEvent(
kind: BusEvent["kind"],
level: BusEvent["level"],
message: string,
meta?: BusEvent["meta"],
): BusEvent {
seq += 1;
return {
id: `evt-${Date.now().toString(36)}-${seq}`,
t: performance.now(),
kind,
level,
message,
meta,
};
}
/**
* Spatial Syncer — Instant Presence media clock.
* Control plane ticks freely; data plane may lag without blocking L0.
*
* WO-5 T2 note: deliberately NOT wired to `miranda-transport`'s telemetry
* `tUs` (see `mirandaTransport.ts`). This clock drives the browser's own
* idle-animation loop and must keep advancing on `performance.now()` alone
* regardless of network state — that is the decoupled-render-loop guardrail
* this Work Order specifies: the avatar's motion may never depend on a
* network tick arriving. Server telemetry timestamps are for the telemetry
* dashboard's own display, not for driving local animation.
*/
export class SpatialSyncer {
private started = performance.now();
private mediaOffset = 0;
private lastWall = performance.now();
private pulses = 0;
private ppsWindowStart = performance.now();
private pps = 0;
reset() {
this.started = performance.now();
this.mediaOffset = 0;
this.lastWall = this.started;
this.pulses = 0;
this.ppsWindowStart = this.started;
this.pps = 0;
}
/** Advance media clock; optional intentional slip for degraded links */
tick(slipMs = 0): MediaClockSnapshot {
const now = performance.now();
this.mediaOffset += Math.max(0, slipMs);
this.pulses += 1;
if (now - this.ppsWindowStart >= 1000) {
this.pps = this.pulses;
this.pulses = 0;
this.ppsWindowStart = now;
}
const tMediaMs = now - this.started - this.mediaOffset;
const wallDelta = now - this.lastWall;
this.lastWall = now;
const expected = 1000 / 30;
const driftMs = wallDelta - expected;
return {
tMediaMs,
wallIso: new Date().toISOString(),
driftMs: Math.round(driftMs * 10) / 10,
pps: this.pps,
};
}
stageMessage(from: PresenceStage, to: PresenceStage): BusEvent {
return createBusEvent(
"stage",
to === "L0" ? "info" : "ok",
`Stage ${from} → ${to}`,
{ from, to },
);
}
}
export const globalSyncer = new SpatialSyncer();