chore(k1): checkpoint connection recovery work

This commit is contained in:
DCCONSTRUCTIONS
2026-08-21 08:12:22 +03:00
parent a3138f3d71
commit c7843a3c7e
22 changed files with 969 additions and 293 deletions
@@ -292,6 +292,21 @@ export function isLiveRerunPresentationReady(
isUsableRecordedPlaybackRange(rangeNs);
}
/**
* `recording_open` can arrive before Rerun has registered the live timeline.
* Selecting it at that point is a silent no-op, so keep retrying only until
* the exact live timeline is both available and active.
*/
export function liveTimelineNeedsSynchronization(
followLive: boolean,
activeTimeline: string | null | undefined,
rangeNs: { min: number; max: number } | null,
): boolean {
return followLive &&
isUsableRecordedPlaybackRange(rangeNs) &&
activeTimeline !== "stream_time";
}
/**
* Key the native receiver to its data-plane binding. Recovery authority is a
* retry fence projected from changing supervisor snapshots; it must not tear
@@ -1435,6 +1450,7 @@ export function RerunViewport({
let rangeNs = viewer.get_time_range(event.recording_id, timeline);
let currentNs = viewer.get_current_time(event.recording_id, timeline);
let playing = viewer.get_playing(event.recording_id);
let liveTimelineSynchronized = !followLive;
if (!followLive && playing) {
try {
viewer.set_playing(event.recording_id, false);
@@ -1496,6 +1512,17 @@ export function RerunViewport({
if (disposed || !playbackState) return;
try {
rangeNs = viewer.get_time_range(event.recording_id, timeline);
if (followLive && !liveTimelineSynchronized) {
let activeTimeline = viewer.get_active_timeline(event.recording_id);
if (liveTimelineNeedsSynchronization(followLive, activeTimeline, rangeNs)) {
// The first selection above may have raced timeline
// creation. Once a real range exists this retry is safe
// and preserves Rerun's native live-following cursor.
viewer.set_active_timeline(event.recording_id, timeline);
activeTimeline = viewer.get_active_timeline(event.recording_id);
}
liveTimelineSynchronized = activeTimeline === timeline;
}
currentNs = viewer.get_current_time(event.recording_id, timeline);
playing = viewer.get_playing(event.recording_id);
} catch {
@@ -1511,7 +1538,7 @@ export function RerunViewport({
setRecordingBufferProgress(recordedBuffer.bufferProgress);
}
const readyToRender = followLive
? isLiveRerunPresentationReady(
? liveTimelineSynchronized && isLiveRerunPresentationReady(
viewerStartResolved,
rangeNs,
liveActivitySequenceRef.current,