refactor(viewer): profile rerun loading by playback stage

This commit is contained in:
DCCONSTRUCTIONS
2026-08-29 17:46:07 +03:00
parent 856b61be99
commit c06b709fd7
21 changed files with 1313 additions and 609 deletions
@@ -0,0 +1,98 @@
import assert from "node:assert/strict";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let laboratoryRecordedEvidenceDemand;
let e47SemanticChunkWindowStarts;
let cancelE47SemanticRequestsOutsideWindow;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({ laboratoryRecordedEvidenceDemand } = await server.ssrLoadModule(
"/src/core/laboratory/recordedEvidenceProfile.ts",
));
({
e47SemanticChunkWindowStarts,
cancelE47SemanticRequestsOutsideWindow,
} = await server.ssrLoadModule(
"/src/workspaces/laboratory/useE47SemanticTimeline.ts",
));
});
after(async () => {
await server?.close();
});
test("camera-only LAB presentation does not acquire hidden spatial or semantic payloads", () => {
assert.deepEqual(laboratoryRecordedEvidenceDemand({
mediaMode: "video",
spatialMode: null,
showMediaSemantic: false,
showSpatialSemantic: true,
showMediaPoints: false,
classifiedSpatialMode: "overlay",
}), {
sourceTimelineMetadata: true,
recordedVideo: true,
exactCameraFrame: false,
sourceSpatialPoints: false,
cameraPointOverlay: false,
selectedSemanticMask: false,
selectedSemanticPoints: false,
classifiedSpatial: false,
});
});
test("visible M4 layers acquire only their selected camera and spatial evidence", () => {
assert.deepEqual(laboratoryRecordedEvidenceDemand({
mediaMode: "camera",
spatialMode: "plan",
showMediaSemantic: true,
showSpatialSemantic: true,
showMediaPoints: true,
classifiedSpatialMode: "overlay",
}), {
sourceTimelineMetadata: true,
recordedVideo: false,
exactCameraFrame: true,
sourceSpatialPoints: true,
cameraPointOverlay: true,
selectedSemanticMask: true,
selectedSemanticPoints: true,
classifiedSpatial: true,
});
});
test("a classified replacement does not also load the hidden source point track", () => {
const demand = laboratoryRecordedEvidenceDemand({
mediaMode: null,
spatialMode: "3d",
showMediaSemantic: false,
showSpatialSemantic: false,
showMediaPoints: false,
classifiedSpatialMode: "replace-source",
});
assert.equal(demand.sourceSpatialPoints, false);
assert.equal(demand.classifiedSpatial, true);
});
test("semantic point chunks are ordered active-first and stale requests are cancelled", () => {
assert.deepEqual(e47SemanticChunkWindowStarts(48, 4_489), [48, 72, 96, 24]);
assert.deepEqual(e47SemanticChunkWindowStarts(0, 4_489), [0, 24, 48]);
const cancelled = [];
const requests = new Map([
[0, { abort: () => cancelled.push(0) }],
[24, { abort: () => cancelled.push(24) }],
[240, { abort: () => cancelled.push(240) }],
]);
cancelE47SemanticRequestsOutsideWindow(requests, [240, 264]);
assert.deepEqual(cancelled, [0, 24]);
assert.deepEqual([...requests.keys()], [240]);
});
@@ -7,6 +7,7 @@ let createLiveViewerDiagnosticLifecycle;
let createAbortFencedBuildVerifier;
let createUiBuildStaleCoordinator;
let liveViewerDiagnosticBody;
let reloadRecordedViewerAfterStaleModuleFailure;
let server;
let uiBuildIdFromModuleScripts;
let verifyLiveViewerClientBuild;
@@ -22,6 +23,7 @@ before(async () => {
createLiveViewerDiagnosticLifecycle,
createUiBuildStaleCoordinator,
liveViewerDiagnosticBody,
reloadRecordedViewerAfterStaleModuleFailure,
uiBuildIdFromModuleScripts,
verifyLiveViewerClientBuild,
} = await server.ssrLoadModule("/src/core/observation/liveViewerDiagnostics.ts"));
@@ -204,6 +206,36 @@ test("build drift is reported once with the exact loaded build", async () => {
);
});
test("a recorded viewer reloads only when its failed lazy module belongs to a stale build", async () => {
const reloads = [];
const loadedUiBuildId = "/assets/index-abcdefgh.js";
const currentUiBuildId = "/assets/index-ijklmnop.js";
const fetcher = async (_url, options) => {
assert.equal(options.headers["X-MissionCore-UI-Build"], loadedUiBuildId);
return new Response(JSON.stringify({}), {
status: 200,
headers: { "X-MissionCore-UI-Build": currentUiBuildId },
});
};
assert.equal(await reloadRecordedViewerAfterStaleModuleFailure({
loadedUiBuildId,
fetcher,
reload: () => reloads.push("reload"),
}), true);
assert.deepEqual(reloads, ["reload"]);
assert.equal(await reloadRecordedViewerAfterStaleModuleFailure({
loadedUiBuildId: currentUiBuildId,
fetcher: async () => new Response(JSON.stringify({}), {
status: 200,
headers: { "X-MissionCore-UI-Build": currentUiBuildId },
}),
reload: () => reloads.push("unexpected"),
}), false);
assert.deepEqual(reloads, ["reload"]);
});
test("last unsubscribe fences an already queued build verification callback", () => {
const controller = new AbortController();
const observedSignals = [];
@@ -932,7 +932,7 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
assert.match(visual, /timelineFrame\.availableFrames\.find/);
assert.match(visual, /localSurfaceBodyXyzM=\{localSurface\.pointsBodyXyzM\}/);
assert.match(visual, /showLocalSurface=\{showLocalSurface\}/);
assert.match(visual, /\{semantic \? \([\s\S]*>\s*SEMANTICS\s*<\/Button>/);
assert.match(visual, /\{activeSemantic \? \([\s\S]*>\s*SEMANTICS\s*<\/Button>/);
assert.match(visual, /current safety — все \{classifiedCellCount\.toLocaleString\("ru-RU"\)\} TGS-ячейки UNOBSERVED/);
assert.match(
visual,
@@ -11,7 +11,11 @@ let recordedMediaSeekableCoverage;
let recordedMediaFragmentUrl;
let recordedMediaDecodeStartSequence;
let recordedMediaSegmentAppendOrder;
let recordedMediaSegmentSequenceAtTime;
let recordedMediaCanRollTarget;
let nextRecordedMediaRandomAccessSequence;
let recordedMediaRecoveryTargetSequence;
let selectRecordedMediaPreparationEpoch;
before(async () => {
server = await createServer({
@@ -26,7 +30,11 @@ before(async () => {
recordedMediaFragmentUrl,
recordedMediaDecodeStartSequence,
recordedMediaSegmentAppendOrder,
recordedMediaSegmentSequenceAtTime,
recordedMediaCanRollTarget,
nextRecordedMediaRandomAccessSequence,
recordedMediaRecoveryTargetSequence,
selectRecordedMediaPreparationEpoch,
} = await server.ssrLoadModule("/src/components/RecordedFmp4Player.tsx"));
});
@@ -161,7 +169,7 @@ test("decoded duration and seekable range cover the complete declared epoch", ()
assert.equal(recordedMediaSeekableCoverage(20, 20, 20, 1, 1.01), false);
});
test("recorded player keeps full-archive range fallback and uses bounded generation-bound fragments", async () => {
test("production replay derives bounded fragments and retains native range fallback", async () => {
const source = await readFile(
new URL("../src/components/RecordedFmp4Player.tsx", import.meta.url),
"utf8",
@@ -176,6 +184,10 @@ test("recorded player keeps full-archive range fallback and uses bounded generat
assert.match(source, /hasPresentedFrame/);
assert.match(source, /retainForwardFrame/);
assert.match(source, /candidateTarget\.sequence >= previousTarget\.sequence/);
assert.match(source, /effectiveSegmentCount = segmentCount \?\? epoch\?\.segmentCount \?\? null/);
assert.match(source, /requestedSegmentSequence = segmentSequence \?\?/);
assert.match(source, /waitForRecordedVideoInitialFrame/);
assert.match(source, /setSegmentRecoveryGeneration/);
assert.equal(recordedMediaDecodeStartSequence([1, 1491, 1501], 1500), 1491);
assert.deepEqual(
@@ -209,6 +221,44 @@ test("recorded player keeps full-archive range fallback and uses bounded generat
);
});
test("production replay derives its bounded fragment directly from the source clock", () => {
const ends = [0.101, 0.185, 0.286, 0.401];
const epochStart = 39.215263458;
assert.equal(recordedMediaSegmentSequenceAtTime(ends, epochStart, epochStart), 1);
assert.equal(recordedMediaSegmentSequenceAtTime(ends, epochStart, epochStart + 0.101), 1);
assert.equal(recordedMediaSegmentSequenceAtTime(ends, epochStart, epochStart + 0.103), 2);
assert.equal(recordedMediaSegmentSequenceAtTime(ends, epochStart, epochStart + 0.4), 4);
assert.equal(recordedMediaSegmentSequenceAtTime(ends, epochStart, epochStart + 1), null);
});
test("a corrupt fragment advances recovery to the next random-access frame", () => {
assert.equal(nextRecordedMediaRandomAccessSequence([1, 11, 21, 49], 1), 11);
assert.equal(nextRecordedMediaRandomAccessSequence([1, 11, 21, 49], 20), 21);
assert.equal(nextRecordedMediaRandomAccessSequence([1, 11, 21, 49], 49), null);
assert.equal(nextRecordedMediaRandomAccessSequence([1, 11, 21, 49], 0), null);
});
test("paused seek displays the recovery keyframe until the source clock leaves the corrupt GOP", () => {
assert.equal(recordedMediaRecoveryTargetSequence(120, 120, 149), 149);
assert.equal(recordedMediaRecoveryTargetSequence(130, 120, 149), 149);
assert.equal(recordedMediaRecoveryTargetSequence(119, 120, 149), 119);
assert.equal(recordedMediaRecoveryTargetSequence(149, 120, 149), 149);
assert.equal(recordedMediaRecoveryTargetSequence(151, 120, 149), 151);
assert.equal(recordedMediaRecoveryTargetSequence(null, 120, 149), null);
assert.equal(recordedMediaRecoveryTargetSequence(120, null, null), 120);
});
test("camera admission selects one bounded epoch while the shared clock is outside video", () => {
const epochs = [
{ ordinal: 1, timelineStartSeconds: 39, timelineEndSeconds: 100 },
{ ordinal: 2, timelineStartSeconds: 120, timelineEndSeconds: 180 },
];
assert.equal(selectRecordedMediaPreparationEpoch(epochs, 0).ordinal, 1);
assert.equal(selectRecordedMediaPreparationEpoch(epochs, 70).ordinal, 1);
assert.equal(selectRecordedMediaPreparationEpoch(epochs, 110).ordinal, 2);
assert.equal(selectRecordedMediaPreparationEpoch(epochs, 200).ordinal, 2);
});
test("recorded player preserves forward rolling playback but seeks backward clip loops", () => {
assert.equal(recordedMediaCanRollTarget(20, 21, true, true), true);
assert.equal(recordedMediaCanRollTarget(20, 20, true, true), true);
@@ -34,7 +34,7 @@ function camera(phase, byteLength = 1_024) {
return { phase, byteLength, message: null };
}
test("recorded session admits RRD and every declared camera as one atomic generation", () => {
test("recorded session keeps camera and timeline atomic without hiding a ready spatial frame", () => {
const ids = ["camera.left", "camera.right"];
const oneCamera = {
"camera.left": camera("ready"),
@@ -42,7 +42,7 @@ test("recorded session admits RRD and every declared camera as one atomic genera
};
const partialGate = admission.recordedSessionAdmissionPhase("ready", ids, oneCamera);
assert.equal(partialGate, "loading");
assert.equal(rerunPresentationStatus("ready", partialGate, true), "loading");
assert.equal(rerunPresentationStatus("ready", partialGate, true), "ready");
assert.equal(
recordedMediaPresentationState("ready", "generation", "generation", false, partialGate),
"loading",
@@ -71,7 +71,7 @@ test("any RRD or camera failure closes the complete recorded session", () => {
...cameras,
"camera.right": camera("ready"),
}), "error");
assert.equal(rerunPresentationStatus("ready", "error", true), "error");
assert.equal(rerunPresentationStatus("ready", "error", true), "ready");
assert.equal(
recordedMediaPresentationState("ready", "generation", "generation", false, "error"),
"error",
@@ -257,6 +257,14 @@ test("recorded RRD bytes are never split across LogChannel.send_rrd calls", asyn
source,
/if \(readyToRender && !readyPublished\)[\s\S]*clearRecordedAdmissionWatchdog\(\);/,
);
assert.match(
source,
/reloadRecordedViewerAfterStaleModuleFailure\(\{[\s\S]*loadedUiBuildId: diagnosticLifecycle\.lineage\.uiBuildId/,
);
assert.match(
source,
/!recordedPerceptionUrl \|\| !recordedPerceptionLayers\.enabled/,
);
});
test("one live document owns one native Rerun receiver", async () => {
@@ -287,8 +295,12 @@ test("raw replay exercises the same streaming receiver lifecycle as a live scan"
source,
/const livePresentationActivitySequence = metrics\?\.publishedFrameCount \?\?[\s\S]*liveRerunSource && !streamActive \? 1 : null/,
);
assert.match(source, /followLive=\{liveRerunSource\}/);
assert.match(source, /liveActivitySequence=\{livePresentationActivitySequence\}/);
assert.match(
source,
/liveAcquisitionRerunProfile\(\{[\s\S]*liveActivitySequence: livePresentationActivitySequence/,
);
assert.match(source, /<RerunViewport[\s\S]*profile=\{rerunViewerProfile\}/);
assert.doesNotMatch(source, /followLive=\{liveRerunSource\}/);
assert.match(
source,
/sourceUrl\.trim\(\) && pointCloudVisible && !intentionalSourceEnd/,
@@ -11,6 +11,7 @@ let isRecordedPlaybackPresentationReady;
let isUsableRecordedPlaybackRange;
let recordedPlaybackBufferState;
let recordedPlaybackRangeWhenReady;
let rerunPresentationStatus;
before(async () => {
server = await createServer({
@@ -26,6 +27,7 @@ before(async () => {
isUsableRecordedPlaybackRange,
recordedPlaybackBufferState,
recordedPlaybackRangeWhenReady,
rerunPresentationStatus,
} = await server.ssrLoadModule("/src/components/RerunViewport.tsx"));
});
@@ -33,7 +35,7 @@ after(async () => {
await server?.close();
});
test("a first frame reports buffer telemetry but is not ready for presentation", () => {
test("a verified first frame is presentable while full-range controls stay closed", () => {
assert.equal(isUsableRecordedPlaybackRange(null), false);
assert.equal(isUsableRecordedPlaybackRange({ min: Number.NaN, max: 0 }), false);
assert.equal(isUsableRecordedPlaybackRange({ min: 2, max: 1 }), false);
@@ -47,8 +49,11 @@ test("a first frame reports buffer telemetry but is not ready for presentation",
bufferProgress: 0,
fullyBuffered: false,
});
assert.equal(isRecordedPlaybackReady(true, true, firstFrame), false);
assert.equal(isRecordedPlaybackReady(true, true, firstFrame), true);
assert.equal(recordedPlaybackRangeWhenReady({ min: 0, max: 0 }, firstFrame, true), null);
assert.equal(rerunPresentationStatus("ready", "loading", true), "ready");
assert.equal(rerunPresentationStatus("loading", "ready", true), "loading");
assert.equal(rerunPresentationStatus("ready", "error", true), "ready");
});
test("host timeline remains unmounted until the verified recording is fully ready", () => {
@@ -107,7 +112,7 @@ test("buffer progress grows independently and preserves the full-buffer toleranc
);
assert.equal(missingDeclaredStart.bufferProgress, 1);
assert.equal(missingDeclaredStart.fullyBuffered, false);
assert.equal(isRecordedPlaybackReady(true, true, missingDeclaredStart), false);
assert.equal(isRecordedPlaybackReady(true, true, missingDeclaredStart), true);
});
test("a verified split boundary spill covers and clamps the declared LAB window", () => {
@@ -81,7 +81,7 @@ test("M4 keeps independent semantic controls in media and spatial panes", async
);
assert.match(source, /showMediaSemantic/);
assert.match(source, /showSpatialSemantic/);
assert.match(source, /semantic && showMediaSemantic && frame/);
assert.match(source, /activeSemantic && evidenceDemand\.selectedSemanticMask && frame/);
assert.match(source, /Array\.from\(\{ length: 12 \}, \(_, index\) => index \+ 1\)/);
assert.match(source, /\|\| !showSpatialSemantic/);
assert.match(source, /aria-label="Слои камеры и видео"/);
@@ -0,0 +1,88 @@
import assert from "node:assert/strict";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let LABORATORY_RECORDED_EVIDENCE_VIEWER_PROFILE;
let liveAcquisitionRerunProfile;
let recordedSessionRerunProfile;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({
LABORATORY_RECORDED_EVIDENCE_VIEWER_PROFILE,
liveAcquisitionRerunProfile,
recordedSessionRerunProfile,
} = await server.ssrLoadModule("/src/core/observation/viewerProfile.ts"));
});
after(async () => {
await server?.close();
});
test("live acquisition profile cannot acquire recorded playback policy", () => {
assert.deepEqual(liveAcquisitionRerunProfile({
sourceUrl: "rerun+http://127.0.0.1:9877/proxy",
liveActivitySequence: 12,
liveStreamId: "acquisition-1",
liveRecoveryAuthorityIdentity: "authority-1",
}), {
kind: "live-acquisition",
clock: "stream_time",
sourceUrl: "rerun+http://127.0.0.1:9877/proxy",
liveActivitySequence: 12,
liveStreamId: "acquisition-1",
liveRecoveryAuthorityIdentity: "authority-1",
});
});
test("recorded session profile owns progressive admission and on-demand layers", () => {
const artifact = {
sourceUrl: "/api/v1/observation-sessions/session-1/recording.rrd",
viewerSourceUrl: "/api/v1/observation-sessions/session-1/recording.rrd?generation=abc",
byteLength: 42,
sha256: "a".repeat(64),
};
const profile = recordedSessionRerunProfile({
sourceUrl: artifact.sourceUrl,
artifact,
autoplayWhenReady: true,
presentationGate: "loading",
expectedTimelineStartSeconds: 0,
expectedTimelineEndSeconds: 20,
initialPlaybackStartSeconds: 1,
view: "spatial",
viewResetGeneration: 0,
followTrajectory: false,
perceptionLayers: {
enabled: false,
detections2d: false,
segmentation: false,
cuboids3d: false,
},
perceptionRetryGeneration: 0,
lockPerceptionCameraInteraction: false,
});
assert.equal(profile.kind, "recorded-session");
assert.equal(profile.clock, "session_time");
assert.equal(profile.artifact, artifact);
assert.equal(profile.perceptionLayers.enabled, false);
});
test("LAB recorded evidence remains outside native Rerun lifecycle", () => {
assert.deepEqual(LABORATORY_RECORDED_EVIDENCE_VIEWER_PROFILE, {
kind: "lab-recorded-evidence",
clock: "source-sequence",
cameraTransport: "generation-bound-fmp4",
spatialTransport: "bounded-sealed-artifacts",
loadPolicy: "visible-evidence-only",
workerRequired: false,
});
assert.equal(Object.isFrozen(LABORATORY_RECORDED_EVIDENCE_VIEWER_PROFILE), true);
});