diff --git a/biome.json b/biome.json index 4c8efc5..68614e8 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.2/schema.json", "assist": { "actions": { "source": { @@ -51,6 +51,7 @@ "useNamingConvention": { "level": "warn", "options": { + "strictCase": false, "conventions": [ { "selector": { "kind": "variable" }, @@ -75,7 +76,8 @@ "level": "warn", "options": { "requireAscii": true, - "filenameCases": ["PascalCase", "camelCase"] + "strictCase": false, + "filenameCases": ["PascalCase", "camelCase", "kebab-case"] } } }, diff --git a/src/i18n/StringManager.ts b/src/i18n/StringManager.ts index 9aa69e4..1480f82 100644 --- a/src/i18n/StringManager.ts +++ b/src/i18n/StringManager.ts @@ -13,10 +13,10 @@ import stringsFr from "./strings_fr.json"; // These type aliases exist solely so TypeScript verifies that both language files // share identical key structures. If a key is added to one file but not the // other, a type error will appear here before the app is ever run. -type _EnMatchesFr = typeof stringsEn extends typeof stringsFr ? true : never; -type _FrMatchesEn = typeof stringsFr extends typeof stringsEn ? true : never; +type EnMatchesFr = typeof stringsEn extends typeof stringsFr ? true : never; +type FrMatchesEn = typeof stringsFr extends typeof stringsEn ? true : never; // Force evaluation (unused types are not checked without a reference). -declare const _parity: _EnMatchesFr & _FrMatchesEn; +declare const _parity: EnMatchesFr & FrMatchesEn; /** * Manages all localized strings for the simulation diff --git a/src/screen-name/graph/ConfigurableGraph.ts b/src/screen-name/graph/ConfigurableGraph.ts index a2ff99e..18bb755 100644 --- a/src/screen-name/graph/ConfigurableGraph.ts +++ b/src/screen-name/graph/ConfigurableGraph.ts @@ -470,9 +470,9 @@ export default class ConfigurableGraph extends Node { this.graphContentNode.visible = visible; this.headerBar.visible = visible; this.titlePanel.visible = visible; - resizeHandles.forEach((handle) => { + for (const handle of resizeHandles) { handle.visible = visible; - }); + } }; this.graphVisibleProperty.link(graphVisibleListener); diff --git a/src/screen-name/graph/GraphDataManager.ts b/src/screen-name/graph/GraphDataManager.ts index fc735ad..b67a33e 100644 --- a/src/screen-name/graph/GraphDataManager.ts +++ b/src/screen-name/graph/GraphDataManager.ts @@ -76,6 +76,7 @@ export default class GraphDataManager { const result: Vector2[] = new Array(this.dataSize); for (let i = 0; i < this.dataSize; i++) { const idx = (this.dataHead - this.dataSize + i + this.maxDataPoints) % this.maxDataPoints; + // biome-ignore lint/style/noNonNullAssertion: index is within dataSize, slot is always written result[i] = this.dataBuf[idx]!; } return result; @@ -109,11 +110,20 @@ export default class GraphDataManager { this.yMax = -Infinity; for (let i = 0; i < this.dataSize; i++) { const idx = (this.dataHead - this.dataSize + i + this.maxDataPoints) % this.maxDataPoints; + // biome-ignore lint/style/noNonNullAssertion: index is within dataSize, slot is always written const p = this.dataBuf[idx]!; - if (p.x < this.xMin) this.xMin = p.x; - if (p.x > this.xMax) this.xMax = p.x; - if (p.y < this.yMin) this.yMin = p.y; - if (p.y > this.yMax) this.yMax = p.y; + if (p.x < this.xMin) { + this.xMin = p.x; + } + if (p.x > this.xMax) { + this.xMax = p.x; + } + if (p.y < this.yMin) { + this.yMin = p.y; + } + if (p.y > this.yMax) { + this.yMax = p.y; + } } } @@ -123,10 +133,18 @@ export default class GraphDataManager { * axis extreme (the common case — a buffer that has never filled — never rescans). */ private updateMinMaxIncremental(x: number, y: number, evicted: Vector2 | undefined): void { - if (x < this.xMin) this.xMin = x; - if (x > this.xMax) this.xMax = x; - if (y < this.yMin) this.yMin = y; - if (y > this.yMax) this.yMax = y; + if (x < this.xMin) { + this.xMin = x; + } + if (x > this.xMax) { + this.xMax = x; + } + if (y < this.yMin) { + this.yMin = y; + } + if (y > this.yMax) { + this.yMax = y; + } if ( evicted !== undefined && (evicted.x <= this.xMin || evicted.x >= this.xMax || evicted.y <= this.yMin || evicted.y >= this.yMax) @@ -190,10 +208,18 @@ export default class GraphDataManager { if (Number.isFinite(x) && Number.isFinite(y)) { const evicted = this.writePoint(x, y); // Inline incremental update (avoids function-call overhead in tight loop). - if (x < this.xMin) this.xMin = x; - if (x > this.xMax) this.xMax = x; - if (y < this.yMin) this.yMin = y; - if (y > this.yMax) this.yMax = y; + if (x < this.xMin) { + this.xMin = x; + } + if (x > this.xMax) { + this.xMax = x; + } + if (y < this.yMin) { + this.yMin = y; + } + if (y > this.yMax) { + this.yMax = y; + } if ( evicted !== undefined && (evicted.x <= this.xMin || evicted.x >= this.xMax || evicted.y <= this.yMin || evicted.y >= this.yMax) diff --git a/src/screen-name/view/AutoTrackerNode.ts b/src/screen-name/view/AutoTrackerNode.ts index ce492b8..a21f310 100644 --- a/src/screen-name/view/AutoTrackerNode.ts +++ b/src/screen-name/view/AutoTrackerNode.ts @@ -243,10 +243,10 @@ export class AutoTrackerNode extends Node { } }) .catch((err: unknown) => { + // biome-ignore lint/suspicious/noConsole: error logging for tracker init failure console.error("AutoTracker: failed to initialise OpenCV tracker:", err); if (this.initVersion === capturedVersion) { - const message = - err instanceof Error ? err.message : "Tracking initialisation failed. Try again."; + const message = err instanceof Error ? err.message : "Tracking initialisation failed. Try again."; this.errorText.string = message; this.errorText.visible = true; this.hintText.visible = true; diff --git a/src/screen-name/view/DataTableNode.ts b/src/screen-name/view/DataTableNode.ts index e1fe891..66517a1 100644 --- a/src/screen-name/view/DataTableNode.ts +++ b/src/screen-name/view/DataTableNode.ts @@ -488,6 +488,7 @@ export class DataTableNode extends Panel { // or colour change) and an incremental row-append on data-only changes // (new points added to existing tracks). During auto-tracking this fires // ~30 times/s, so avoiding unnecessary full DOM rebuilds is critical. + // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: intentionally complex — must handle structural and incremental updates efficiently const rebuildTable = () => { const tracks = model.tracksProperty.value; const unit = unitProperty.value; diff --git a/src/screen-name/view/VideoPlayerNode.ts b/src/screen-name/view/VideoPlayerNode.ts index d6bbde7..64ebe20 100644 --- a/src/screen-name/view/VideoPlayerNode.ts +++ b/src/screen-name/view/VideoPlayerNode.ts @@ -86,6 +86,7 @@ export class VideoPlayerNode extends Node { const isPlayingListener = (isPlaying: boolean) => { if (isPlaying) { this.videoElement.play().catch((err: unknown) => { + // biome-ignore lint/suspicious/noConsole: error logging for video playback failure console.error("Video playback failed:", err); model.isPlayingProperty.value = false; }); diff --git a/src/tracking/OpenCVTracker.ts b/src/tracking/OpenCVTracker.ts index 8943acc..7a0dcc1 100644 --- a/src/tracking/OpenCVTracker.ts +++ b/src/tracking/OpenCVTracker.ts @@ -31,8 +31,15 @@ interface MinMaxLocResult { /** Typed surface of the OpenCV.js module used by this tracker. */ interface Cv { // Constructors + // biome-ignore lint/style/useNamingConvention: OpenCV API uses PascalCase for constructor properties readonly Mat: new () => CvMat; - readonly Rect: new (x: number, y: number, width: number, height: number) => CvRect; + // biome-ignore lint/style/useNamingConvention: OpenCV API uses PascalCase for constructor properties + readonly Rect: new ( + x: number, + y: number, + width: number, + height: number, + ) => CvRect; // Factory from browser ImageData matFromImageData(imageData: ImageData): CvMat; diff --git a/vite.config.js b/vite.config.js index a1a9ec5..a2bb453 100644 --- a/vite.config.js +++ b/vite.config.js @@ -120,9 +120,12 @@ export default defineConfig({ registerType: "autoUpdate", manifest: { name: "trackLab", + // biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys short_name: "trackLab", description: "trackLab simulation", + // biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys theme_color: "#1a1a2e", + // biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys background_color: "#000000", display: "standalone", orientation: "landscape",