fix(lab): make recorded replay seek-safe

This commit is contained in:
DCCONSTRUCTIONS
2026-08-24 02:15:30 +03:00
parent 7400fe2fd7
commit 992c5a8b74
12 changed files with 1096 additions and 287 deletions
@@ -14,6 +14,7 @@ let selectM4ThreatTimelineSequence;
let advanceRecordedEvidencePlayback;
let synchronizeRecordedEvidencePlayback;
let m4ThreatChunkWindowStarts;
let cancelM4ThreatChunkRequestsOutsideWindow;
let buildM4LocalSurface;
const resultId = `m4-threat-replay-${"a".repeat(64)}`;
@@ -38,7 +39,10 @@ before(async () => {
} = await server.ssrLoadModule(
"/src/components/laboratory/useRecordedEvidencePlayback.ts",
));
({ m4ThreatChunkWindowStarts } = await server.ssrLoadModule(
({
m4ThreatChunkWindowStarts,
cancelM4ThreatChunkRequestsOutsideWindow,
} = await server.ssrLoadModule(
"/src/workspaces/laboratory/useM4ThreatTimeline.ts",
));
({ buildM4LocalSurface } = await server.ssrLoadModule(
@@ -375,6 +379,23 @@ test("M4.6 spatial buffering keeps previous, active and two future chunks", () =
assert.deepEqual(m4ThreatChunkWindowStarts(0, 24, 4489), [0, 24, 48]);
});
test("M4.6 spatial buffering drops stale in-flight windows across rapid jumps", () => {
const aborted = [];
const controller = (start) => ({ abort: () => aborted.push(start) });
const inFlight = new Map(
m4ThreatChunkWindowStarts(0, 24, 4489).map((start) => [start, controller(start)]),
);
for (const activeStart of [1488, 4488]) {
const desired = m4ThreatChunkWindowStarts(activeStart, 24, 4489);
cancelM4ThreatChunkRequestsOutsideWindow(inFlight, desired);
for (const start of desired) {
if (!inFlight.has(start)) inFlight.set(start, controller(start));
}
}
assert.deepEqual([...inFlight.keys()], [4464, 4488]);
assert.deepEqual(aborted, [0, 24, 48, 1464, 1488, 1512, 1536]);
});
test("recorded evidence clock advances by selected rate and stops at the sealed end", () => {
const range = { startSeconds: 10, endSeconds: 20 };
assert.deepEqual(
@@ -448,6 +469,7 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
assert.match(visual, /const spatialFrame = frame\?\.spatialAvailable/);
assert.match(visual, /<ObservationTimeline/);
assert.match(visual, /useM4ThreatTimelineFrame/);
assert.match(visual, /resolveObservationSessionReplay\(timeline\.recordedSourceSessionId/);
assert.match(visual, /label: "VIDEO"/);
assert.match(visual, /label: "CAMERA"/);
assert.match(visual, /label: "3D"/);
@@ -463,11 +485,11 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
assert.match(visual, /secondaryMode=\{\{/);
assert.match(visual, /playback=\{playbackController\.playback\}/);
assert.match(visual, /clock: mediaMode === "video" \? "external" : "animation"/);
assert.match(visual, /segmentSequence=\{frame \? frame\.sequence \+ 1 : undefined\}/);
assert.match(visual, /timelineFrame\.activeSequence \+ 1/);
assert.match(visual, /segmentCount=\{timeline\.frameCount\}/);
assert.match(visual, /onPlaybackChange=\{playbackController\.synchronize\}/);
assert.match(visual, /onPlayingRejected=\{\(\) => playbackController\.setPlaying\(false\)\}/);
assert.match(visual, /currentSeconds: playbackController\.playback\.currentSeconds/);
assert.doesNotMatch(visual, /setPlaying\(false\)/);
assert.match(visualCss, /m4-replay-threat-visual__deck > \.nodedc-split-pane/);
assert.match(visualCss, /m4-replay-threat-visual__pane-toolbar\[data-pane-toolbar="media"\]/);
assert.match(visualCss, /m4-replay-threat-visual__pane-toolbar\[data-pane-toolbar="spatial"\]/);