You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Overview: Adds a /hardware page backed by a <hardware-monitor> Lit web component — a digital-twin POC with a Three.js 3D arm view, SVG 2D fallback, ECharts timeline/sparklines, and synthetic telemetry. Clean concept; several polish items before it's production-ready.
Unrelated rtsopts change.-Iw60 (idle GC wakeup every 60 s) is added in the same diff line as the GHC options change. If intentional, it deserves its own commit/explanation; if accidental, drop it.
The Haskell page itself is fine — idiomatic term/data_ use, clean handler.
TypeScript — dead code / unused exports
binding.ts is entirely dead code. Neither KqlSource nor SyntheticSource is imported anywhere; the component calls generateTelemetry() directly. If the intent is a future contract sketch, a code comment in data.ts would convey that without shipping ~80 lines that can't be tested or tree-shaken. Consider removing the file and adding a // TODO: swap generateTelemetry() for a KqlSource comment at the call-site.
aggregateSeverity (data.ts) is exported but never imported.refreshAll() in the component re-implements the same worst-severity fold by hand. Either use the function or don't export it:
- if (sev === 'crit') worst = 'crit';- else if (sev === 'warn' && worst === 'ok') worst = 'warn';+ // use aggregateSeverity(tel, this.activeMetric, this.currentTime) instead
Duplicate time-formatter
fmtSec (inside updateTimelineSeries) and formatT (inside render) are byte-for-byte identical. Extract once at class or module level:
JOINT_IDS constant ignored in scene.ts / schematic2d.ts
The JOINT_IDS constant is exported from data.ts specifically to avoid magic arrays, but both visual files hardcode [1, 2, 3, 4, 5, 6] as JointId[]five or more times (e.g. setJointAngles, setJointStates, setJointValues, setHighlight, the render loop). Import and use the constant:
-for (const j of [1, 2, 3, 4, 5, 6] as JointId[]) {+for (const j of JOINT_IDS) {
Timeline double-fire on click
mountTimeline() registers both an ECharts 'click' handler and a raw 'click' DOM listener on this.timelineEl. Clicking a data point fires both: ECharts emits a precise p.value[0] time, then the raw handler computes a pixel-based time from clientX that will be slightly different. The raw listener should guard with e.stopPropagation() inside the ECharts handler, or the raw listener should only fire when ECharts didn't handle the click (e.g. check p.componentType).
any types despite @types/three being present
@types/three was added as a dependency, but JointHandle still types everything as any:
With the types package present, these should be THREE.Object3D, THREE.Mesh, THREE.MeshBasicMaterial. Same for timelineChart: any / sparkCharts: Record<MetricKind, any> — if ECharts doesn't ship types, a minimal interface ECharts { setOption(o: object): void; on(...): void; dispose(): void; } would still be better than any.
Minor
setCursor series offset is fragile. The cursor update uses new Array(JOINT_IDS.length + 1).fill({}) to skip to the right series index. If the scatter/event series moves, this silently breaks. Address by series name: setOption({ series: [{ name: '__cursor', markLine: { data: [{ xAxis: this.currentTime }] } }] }) — ECharts merges by name when notMerge is omitted.
@types/three listed as a production dep. It's a types-only package and belongs in devDependencies.
sCurve and smooth in data.ts do the same thing.smooth and sCurve are both t*t*(3-2*t) smoothstep. One of them can be removed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #
How to test
Checklist