fix(archive): preserve prepared sessions across restarts

This commit is contained in:
DCCONSTRUCTIONS
2026-07-18 11:08:27 +03:00
parent aa3680948f
commit 574a494759
13 changed files with 398 additions and 132 deletions
@@ -11,7 +11,7 @@ import type {
} from "../core/observation/useObservationSessions";
import "../styles/observation-sessions.css";
type SessionVisualState = "ready" | "processing" | "error";
type SessionVisualState = "ready" | "processing" | "cold" | "error";
export function observationSessionVisualState(
session: ObservationSessionSummary,
@@ -26,12 +26,14 @@ export function observationSessionVisualState(
if (session.preparation.state === "ready" && session.replayable) return "ready";
return "error";
}
return session.status === "recording" ? "processing" : "error";
if (session.status === "recording") return "processing";
return session.replayable ? "cold" : "error";
}
export function observationSessionVisualLabel(state: SessionVisualState): string {
if (state === "ready") return "Готово";
if (state === "processing") return "Обработка";
if (state === "cold") return "Подготовить";
return "Ошибка";
}
@@ -137,8 +137,12 @@
animation: observation-session-processing 1.1s ease-in-out infinite;
}
.observation-session-option i[data-session-visual-state="cold"],
.observation-session-option i[data-session-visual-state="error"] {
background: var(--nodedc-text-muted);
}
.observation-session-option i[data-session-visual-state="error"] {
opacity: 0.48;
}
@@ -160,7 +160,7 @@ test("session catalog exposes authoritative background preparation state", () =>
});
});
test("saved-session rows use only authoritative ready, processing and error states", () => {
test("saved-session rows distinguish durable, active, cold and failed states", () => {
const makeDecoded = (state, overrides = {}) => decodeObservationSessionCatalog({
items: [session({
status: "interrupted",
@@ -187,7 +187,7 @@ test("saved-session rows use only authoritative ready, processing and error stat
observationSessionVisualState(makeDecoded("failed", { status: "recording" })),
"error",
);
assert.equal(observationSessionVisualState(makeDecoded(null)), "error");
assert.equal(observationSessionVisualState(makeDecoded(null)), "cold");
assert.equal(
observationSessionVisualState(makeDecoded(null, { status: "recording" })),
"processing",
@@ -206,6 +206,7 @@ test("saved-session rows use only authoritative ready, processing and error stat
);
assert.equal(observationSessionVisualLabel("ready"), "Готово");
assert.equal(observationSessionVisualLabel("processing"), "Обработка");
assert.equal(observationSessionVisualLabel("cold"), "Подготовить");
assert.equal(observationSessionVisualLabel("error"), "Ошибка");
});