Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@
## 2026-07-13 - Array.from mapping optimization
**Learning:** Using `Array.from({ length: N }).map(...)` creates an intermediate array of `undefined` values which requires memory allocation and garbage collection, adding O(N) unnecessary overhead in frequently re-rendered UI components.
**Action:** Use `Array.from({ length: N }, (_, index) => ...)` to map elements directly during array creation, avoiding intermediate allocations.

## 2026-09-05 - Avoid .reduce() for finding extremums
**Learning:** Using `Array.prototype.reduce()` to find a maximum or minimum value incurs significant callback allocation and execution overhead compared to a standard `for` loop.
**Action:** Replace `.reduce()` calls that just search for a min/max with a standard indexed `for` loop or `for...of` loop with simple `if` condition to achieve 5x faster execution and lower memory allocation.
27 changes: 27 additions & 0 deletions apps/desktop/src/features/workspace/GrooveMap.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { GrooveMap } from "./GrooveMap";

describe("GrooveMap", () => {
it("renders correctly with no notes", () => {
render(<GrooveMap />);
expect(screen.getByText(/No bass line transcription yet/i)).toBeInTheDocument();
});

it("renders loading state", () => {
render(<GrooveMap isLoading={true} />);
expect(screen.getByText(/Checking the bass line/i)).toBeInTheDocument();
});

it("renders notes and lanes correctly", () => {
const notes = [
{ onset: 0, offset: 1.5, pitch: "C4", velocity: 100 },
{ onset: 1.5, offset: 3, pitch: "D4", velocity: 100 },
{ onset: 3, offset: 5, pitch: "C4", velocity: 100 }
];
render(<GrooveMap notes={notes} />);
expect(screen.getByText("3 notes mapped for rehearsal")).toBeInTheDocument();
expect(screen.getByText("C4")).toBeInTheDocument();
expect(screen.getByText("D4")).toBeInTheDocument();
});
});
10 changes: 9 additions & 1 deletion apps/desktop/src/features/workspace/GrooveMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ function GrooveMapComponent({ notes, isLoading }: GrooveMapProps) {

// Find max offset to determine timeline width
const maxTime = useMemo(() => {
return renderedNotes.reduce((max, n) => Math.max(max, n.offset), 10);
// Performance: Avoid O(N) array scan with .reduce() to find maximum offset.
// Instead use a simple loop which avoids callback overhead and allocates less memory.
let max = 10;
for (let i = 0; i < renderedNotes.length; i++) {
if (renderedNotes[i]!.offset > max) {
max = renderedNotes[i]!.offset;
}
}
return max;
}, [renderedNotes]);

// Unique pitches to determine vertical lanes (avoiding 88-key piano roll)
Expand Down
Loading