From 958e24b0fd08e4bc92656964e832606dbf7d3fa3 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Mon, 21 Sep 2026 10:14:24 +0800 Subject: feat(boot): surface pre-published probe replay on landing page - boot loads the completed run from /api/artifacts/manifest and renders its latest checkpoint with concrete build-review labels (no fake unknown-state wording); offline fallback still shows the honest placeholder - artifact manifest/steps endpoints now fall back to disk when a completed run has no in-memory registry entry, keeping pre-published history browsable after a service restart (digest-verified, .glb-only / steps/ / logs/ rejected) - driver: heritage flows pin heritage ids explicitly; new checks for the boot probe replay and its labels; 72/72 green with zero console errors --- public/App.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- public/index.html | 18 +++++++-------- 2 files changed, 72 insertions(+), 11 deletions(-) (limited to 'public') diff --git a/public/App.js b/public/App.js index ab4ae59..a401102 100644 --- a/public/App.js +++ b/public/App.js @@ -1,8 +1,8 @@ import { Union, Record } from "./fable_modules/fable-library-js.4.24.0/Types.js"; import { union_type, class_type, record_type, bool_type, string_type } from "./fable_modules/fable-library-js.4.24.0/Reflection.js"; import { Replay_frames } from "./SomhairlesDream.Shared/Replay.js"; -import { defaultOf, equals, createAtom } from "./fable_modules/fable-library-js.4.24.0/Util.js"; -import { equalsWith, tryFind, iterateIndexed, item } from "./fable_modules/fable-library-js.4.24.0/Array.js"; +import { comparePrimitives, defaultOf, equals, createAtom } from "./fable_modules/fable-library-js.4.24.0/Util.js"; +import { sortBy, map, equalsWith, tryFind, iterateIndexed, item } from "./fable_modules/fable-library-js.4.24.0/Array.js"; import { join, isNullOrWhiteSpace, printf, toText } from "./fable_modules/fable-library-js.4.24.0/String.js"; import { MeshData_triangleIndices, MeshData_positionData } from "./SomhairlesDream.Shared/Domain.js"; import { min, max } from "./fable_modules/fable-library-js.4.24.0/Double.js"; @@ -881,6 +881,66 @@ export function startRun(selection) { }))); } +/** + * Boot-time historical load: surface the pre-published probe build replay so + * first-time visitors see the real vehicle instead of an empty placeholder. + * Any failure leaves the honest placeholder idle state untouched. + */ +export function loadBootHistory() { + const selection = selectedRun(); + const projectId = encodeURIComponent(selection.ProjectId); + const runId = encodeURIComponent(selection.RunId); + const url = toText(printf("/api/artifacts/manifest?projectId=%s&runId=%s"))(projectId)(runId); + const requestOptions = { + method: "GET", + }; + startImmediate(singleton.Delay(() => singleton.TryWith(singleton.Delay(() => singleton.Bind(awaitPromise(fetch(url, requestOptions)), (_arg) => { + const response = _arg; + return response.ok ? singleton.Bind(awaitPromise(response.json()), (_arg_1) => { + let arg_2, arg_3, arg_4, arg_5, arg_6, arg_7, arg_8; + const payload = _arg_1; + if ((payload.status === "complete") && (payload.steps.length > 0)) { + const steps = map((step_1) => step_1.artifactPath, sortBy((step) => step.stepIndex, payload.steps, { + Compare: comparePrimitives, + })); + if (steps.length > 0) { + currentProjectId(selection.ProjectId); + currentRunId(selection.RunId); + historicalSteps(steps); + setText("project-id", selection.ProjectId); + setText("run-id", selection.RunId); + setText("target-version", (arg_2 = (steps.length | 0), toText(printf("V%02d"))(arg_2))); + setText("current-version", (arg_3 = (steps.length | 0), toText(printf("V%02d"))(arg_3))); + setText("version-readout", (arg_4 = (steps.length | 0), (arg_5 = (steps.length | 0), toText(printf("%02d / %02d"))(arg_4)(arg_5)))); + setWidth("progress-fill", "100%"); + setText("updated-at", "预发布历史"); + setText("mesh-label", (arg_6 = item(steps.length - 1, steps), toText(printf("历史 · %s"))(arg_6))); + setText("timeline-current", (arg_7 = (steps.length | 0), (arg_8 = item(steps.length - 1, steps), toText(printf("V%02d · 构建重演 · %s"))(arg_7)(arg_8)))); + setText("replay-button", "播放历史"); + setText("replay-state", "构建重演 · 预发布历史"); + renderTimeline(); + updateFollowButton(); + if (viewState() == null) { + return singleton.Zero(); + } + else { + loadStepArtifact(viewState(), item(steps.length - 1, steps), true); + return singleton.Zero(); + } + } + else { + return singleton.Zero(); + } + } + else { + return singleton.Zero(); + } + }) : singleton.Zero(); + })), (_arg_2) => { + return singleton.Zero(); + }))); +} + export function boot() { showFrameMetadata(item(0, frames)); try { @@ -902,6 +962,7 @@ export function boot() { event.preventDefault(); startRun(selectedRun()); }); + loadBootHistory(); renderTimeline(); } diff --git a/public/index.html b/public/index.html index 71e9e62..d6966b1 100644 --- a/public/index.html +++ b/public/index.html @@ -32,11 +32,11 @@
PROJECT - heritage-001 + probe-001
RUN - run-001 + run-probe-real-2
MODE @@ -58,19 +58,19 @@
@@ -85,7 +85,7 @@
设计版本 - 00 / 03 + 07 / 07
-- cgit v1.2.3