diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-21 10:14:24 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-21 10:14:24 +0800 |
| commit | 958e24b0fd08e4bc92656964e832606dbf7d3fa3 (patch) | |
| tree | 01606b1c010fecc4d3379cbc796c100c32363bac /src/SomhairlesDream.Frontend | |
| parent | 07d6690b9b9de7db7debe25e8e3def5c0d68bb26 (diff) | |
| download | somhairles-dream-fsharp-958e24b0fd08e4bc92656964e832606dbf7d3fa3.tar.gz | |
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
Diffstat (limited to 'src/SomhairlesDream.Frontend')
| -rw-r--r-- | src/SomhairlesDream.Frontend/App.fs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/SomhairlesDream.Frontend/App.fs b/src/SomhairlesDream.Frontend/App.fs index b2bb8e6..f9184c5 100644 --- a/src/SomhairlesDream.Frontend/App.fs +++ b/src/SomhairlesDream.Frontend/App.fs @@ -23,6 +23,18 @@ type SnapshotPayload = abstract error: string with get abstract isStale: bool with get +[<Erase>] +type ManifestStep = + abstract stepIndex: int with get + abstract artifactPath: string with get + +[<Erase>] +type ManifestPayload = + abstract projectId: string with get + abstract runId: string with get + abstract status: string with get + abstract steps: ManifestStep array with get + type RunSelection = { ProjectId: string RunId: string @@ -687,6 +699,56 @@ let startRun (selection: RunSelection) = } |> Async.StartImmediate +/// 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. +let loadBootHistory () = + let selection = selectedRun () + let projectId = JS.encodeURIComponent selection.ProjectId + let runId = JS.encodeURIComponent selection.RunId + let url = sprintf "/api/artifacts/manifest?projectId=%s&runId=%s" projectId runId + let requestOptions = createObj [ "method" ==> "GET" ] + + async { + try + let! response = fetch (url, requestOptions) |> Async.AwaitPromise + + if response.ok then + let! value = response.json () |> Async.AwaitPromise + let payload = value :?> ManifestPayload + + if payload.status = "complete" && Array.length payload.steps > 0 then + let steps = + payload.steps + |> Array.sortBy (fun step -> step.stepIndex) + |> Array.map (fun step -> step.artifactPath) + + if Array.length steps > 0 then + currentProjectId <- selection.ProjectId + currentRunId <- selection.RunId + historicalSteps <- steps + setText "project-id" selection.ProjectId + setText "run-id" selection.RunId + setText "target-version" (sprintf "V%02d" steps.Length) + setText "current-version" (sprintf "V%02d" steps.Length) + setText "version-readout" (sprintf "%02d / %02d" steps.Length steps.Length) + setWidth "progress-fill" "100%" + setText "updated-at" "预发布历史" + setText "mesh-label" (sprintf "历史 · %s" steps[steps.Length - 1]) + setText "timeline-current" (sprintf "V%02d · 构建重演 · %s" steps.Length steps[steps.Length - 1]) + setText "replay-button" "播放历史" + setText "replay-state" "构建重演 · 预发布历史" + renderTimeline () + updateFollowButton () + + match viewState with + | Some view -> loadStepArtifact view steps[steps.Length - 1] true + | None -> () + with _ -> + () + } + |> Async.StartImmediate + let boot () = showFrameMetadata frames[0] @@ -702,6 +764,8 @@ let boot () = event.preventDefault() startRun (selectedRun ())) + loadBootHistory () + renderTimeline () boot () |
