Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
fbb6bd7
feat: Implement hit testing for timeline markers and refactor renderi…
lukecotter Feb 5, 2026
7ab33aa
Merge branch 'main' into chore-timeline-optimisation
lukecotter Feb 5, 2026
7dbadc3
refactor: optimize rendering in FlameChart and related orchestrators …
lukecotter Feb 6, 2026
344d439
refactor: remove unused viewport state variable and update parameter …
lukecotter Feb 6, 2026
43ee406
refactor: remove unused handleZoom method from MinimapOrchestrator
lukecotter Feb 6, 2026
63ab164
refactor: optimize MeasureRangeRenderer by reusing HTML elements and …
lukecotter Feb 7, 2026
7642dfc
test: add additional hit test cases for large offsets and edge scenarios
lukecotter Feb 7, 2026
ea08f4f
chore: update copyright year from 2025 to 2026 across multiple files
lukecotter Feb 7, 2026
7a3a1f8
refactor: rename minimapHeight parameter to _minimapHeight for consis…
lukecotter Feb 7, 2026
c9547f5
refactor: optimize branch node bounds calculation in TemporalSegmentT…
lukecotter Feb 9, 2026
382f6f4
refactor: remove unused y property from SegmentNode and simplify Temp…
lukecotter Feb 9, 2026
7bbe141
refactor: replace subCategory with rect.category in SearchHighlightRe…
lukecotter Feb 9, 2026
97b3e3b
feat: Implement unified tree conversion with precomputed rectangles f…
lukecotter Feb 9, 2026
ba861a1
refactor: extract mergeNodeCategoryStats function to reduce code dupl…
lukecotter Feb 9, 2026
5a8e3ac
Merge branch 'main' into chore-timeline-optimisation
lukecotter Feb 9, 2026
634247b
refactor: remove unused subCategory property from event objects in Ap…
lukecotter Feb 9, 2026
2b29676
feat: optimize ResizeObserver setup to prevent double rendering on init
lukecotter Feb 10, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe('SearchHighlightRenderer', () => {
timestamp: m.event.timestamp,
duration: m.event.duration,
depth: m.depth,
category: m.event.subCategory ?? '',
category: m.rect.category,
})),
),
};
Expand Down
7 changes: 0 additions & 7 deletions log-viewer/src/features/timeline/__tests__/tooltip.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,6 @@ describe('TimelineTooltipManager', () => {
} as unknown as LogEvent;
}

/**
* Helper to wait for async operations
*/
function wait(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}

beforeEach(() => {
// Create container element
container = document.createElement('div');
Expand Down
39 changes: 32 additions & 7 deletions log-viewer/src/features/timeline/optimised/ApexLogTimeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import type {
} from '../types/flamechart.types.js';
import type { SearchCursor } from '../types/search.types.js';
import { extractMarkers } from '../utils/marker-utils.js';
import { logEventToTreeNode } from '../utils/tree-converter.js';
import { logEventToTreeAndRects } from '../utils/tree-converter.js';
import { FlameChart } from './FlameChart.js';
import { TimelineTooltipManager } from './TimelineTooltipManager.js';

Expand Down Expand Up @@ -123,12 +123,36 @@ export class ApexLogTimeline {
const markers = extractMarkers(this.apexLog);
this.events = this.extractEvents();

// Convert LogEvent to TreeNode structure for search and navigation
// This is Apex-specific: filters out 0-duration events that are invisible
// Also builds navigation maps during traversal to avoid duplicate O(n) work
const { treeNodes, maps } = logEventToTreeNode(this.events);
// Define categories for rectangle indexing (matches FlameChart batch categories)
const categories = new Set([
'Code Unit',
'Workflow',
'Method',
'Flow',
'DML',
'SOQL',
'System Method',
]);

// Initialize FlameChart with Apex-specific callbacks
// Single-pass unified conversion: builds TreeNodes, navigation maps,
// PrecomputedRects, maxDepth, and totalDuration in one O(n) traversal.
// This eliminates redundant traversals previously done by:
// - logEventToTreeNode (tree + maps)
// - TimelineEventIndex.calculateMaxDepth
// - TimelineEventIndex.calculateTotalDuration
// - RectangleManager.flattenEvents
const {
treeNodes,
maps,
rectsByCategory,
rectsByDepth,
rectMap,
maxDepth,
totalDuration,
preSorted,
} = logEventToTreeAndRects(this.events, categories);

// Initialize FlameChart with Apex-specific callbacks and precomputed data
await this.flamechart.init(
container,
this.events,
Expand Down Expand Up @@ -179,6 +203,8 @@ export class ApexLogTimeline {
this.copyToClipboard(marker.summary);
},
},
// Pass precomputed data to skip redundant O(n) traversals
{ maxDepth, totalDuration, rectsByCategory, rectsByDepth, rectMap, preSorted },
);

// Create context menu Lit element (using constructor ensures custom element is registered)
Expand Down Expand Up @@ -231,7 +257,6 @@ export class ApexLogTimeline {
duration: result.event.duration.total,
type: result.event.type ?? result.event.subCategory ?? 'UNKNOWN',
text: result.event.text,
subCategory: result.event.subCategory,
original: result.event,
};

Expand Down
Loading
Loading