diff --git a/.jules/bolt.md b/.jules/bolt.md index d81fd70a..3433fd72 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -17,3 +17,8 @@ **Learning:** When attempting to optimize an O(N^2) array spread operation (`[...existing, talk]`) inside a grouping loop in `groupTalksByTrack`, the purely functional/immutable constraint specified by the team (and the lack of `Map.groupBy` support in Node 20.x Jest environments) means that we must fall back to immutable reductions. **Action:** When constraints require strict immutability without mutation of objects, use `reduce` with object and array spreads (e.g., `{ ...acc, [key]: [...(acc[key] || []), item] }`) even if it introduces O(N^2) overhead for large arrays. Avoid using `push()` or modifying accumulators directly. Always run Prettier/formatting checks before merge to resolve CI failures. + +## 2026-04-29 - Formatting matters for comments + +**Learning:** When adding multi-line comments in `/* */` style in Next.js codebases, always ensure the text begins on a new line after the opening `/*` (e.g., `/*\n * text\n */`) to avoid 'Expected a linebreak after /\*' and consecutive single-line comment errors. +**Action:** Validate comment structures via `npm run lint` closely when documenting Bolt optimizations. diff --git a/components/schedule/ScheduleContainer.tsx b/components/schedule/ScheduleContainer.tsx index 33d877a4..283c1537 100644 --- a/components/schedule/ScheduleContainer.tsx +++ b/components/schedule/ScheduleContainer.tsx @@ -20,7 +20,13 @@ export default function ScheduleContainer({ initialSchedule, year }: Readonly sessions.filter((s) => savedSessionIds.includes(s.id) || s.isServiceSession); + /* + * ⚡ Bolt: Optimize array lookup from O(N*M) to O(N+M) + * By converting the saved sessions array to a Set before filtering, + * we prevent O(N^2) time complexity when filtering large session lists + */ + const savedSessionIdsSet = new Set(savedSessionIds); + const filterSessions = (sessions: GridSession[]) => sessions.filter((s) => savedSessionIdsSet.has(s.id) || s.isServiceSession); return initialSchedule.map((day) => ({ ...day, diff --git a/hooks/useTalks.ts b/hooks/useTalks.ts index 5dc92f83..80848fe6 100644 --- a/hooks/useTalks.ts +++ b/hooks/useTalks.ts @@ -129,7 +129,13 @@ export const groupTalksByTrack = (talks: Talk[]): Map => { */ export const getTalkSpeakersWithDetails = async (year: string | number, speakerIds: string[]): Promise => { const speakers = await getSpeakers(year); - return speakers.filter((s) => speakerIds.includes(s.id)); + /* + * ⚡ Bolt: Optimize array lookup from O(N*M) to O(N+M) + * Converting speakerIds to a Set to prevent nested iterations + * when matching speakers against the main speaker list + */ + const speakerIdsSet = new Set(speakerIds); + return speakers.filter((s) => speakerIdsSet.has(s.id)); }; export const getRelatedTalksByTrack = async (year: string | number, track: string, excludeTalkId: string, limit: number = 5): Promise => {