feat: v0.14.0 — ISS-006 time-scale slider values up to 1000x; tests use fastest time
CI / build + unit + e2e (pull_request) Failing after 4m52s

This commit is contained in:
2026-09-19 08:49:30 +00:00
parent 0c9279818a
commit bd00b2b4c4
18 changed files with 141 additions and 80 deletions
+6 -5
View File
@@ -14,9 +14,10 @@ interface LeftPaneProps {
onRefresh: () => void;
}
// Power-of-two slider (v0.9.2): position t ∈ [0,1] → nearest step of the ladder
// 1×/2×/4×/8×/16×/32×/64× — each of the 7 positions doubles the speed.
const SCALE_SLIDER_STEP = 1 / (TIME_SCALES.length - 1); // one doubling per keyboard-arrow step
// Discrete ladder slider (v0.9.2, values reworked in v0.14.0): position t ∈ [0,1] → nearest
// step of the ladder 1×/2×/5×/10×/25×/50×/100×/250×/500×/1000× — each of the 10 positions
// roughly doubles the speed.
const SCALE_SLIDER_STEP = 1 / (TIME_SCALES.length - 1); // one ladder step per keyboard-arrow step
const SCALE_COMMIT_DEBOUNCE_MS = 250;
// Flying planes show their current leg from the snapshot's dest fields (v0.12.0).
@@ -48,7 +49,7 @@ export default function LeftPane({ state, loading, error, onRefresh }: LeftPaneP
// controls without waiting for the next poll tick. On failure keep the stale UI — the
// running poll retries on its own and surfaces the error state. A commit that lands while
// another POST is in flight is held in a single slot (last intent wins) and flushed by the
// in-flight call, so every user intent reaches the server (the [1,64] clamp stays as backstop).
// in-flight call, so every user intent reaches the server (the [1,1000] clamp stays as backstop).
// The gate is a REF, not React state: closures never see a stale "busy" value, which used to
// let a flush re-queue instead of send and silently drop a commit.
const queuedRef = useRef<{ timeScale?: number; paused?: boolean } | null>(null);
@@ -101,7 +102,7 @@ export default function LeftPane({ state, loading, error, onRefresh }: LeftPaneP
// Slider commit (v0.9.1): the displayed value follows the drag optimistically via
// pendingScale; POST /api/sim fires after a 250 ms debounce, or immediately when the
// user releases the slider (browsers fire a native 'change' on release). The server's
// [1,64] clamp stays as the backstop.
// [1,1000] clamp stays as the backstop.
const [pendingScale, setPendingScaleState] = useState<number | null>(null);
const pendingRef = useRef<number | null>(null);
const commitTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);