From 762e343666963e63baa4de1c71b5f203b451a371 Mon Sep 17 00:00:00 2001 From: Le Vivilet Date: Sun, 10 May 2026 19:59:01 +0000 Subject: [PATCH 1/2] refactor: Simplify event loading by passing loadSelectedEvent directly to relevant functions --- .../HandleEventRowClick.ts | 15 ++++++++----- .../HandleEventRowClickAt.ts | 6 ++++- .../SelectEventAtIndex/SelectEventAtIndex.ts | 12 +++------- .../test/HandleEventRowClickAt.test.ts | 22 ++++++++++--------- .../test/SelectEventAtIndex.test.ts | 12 +++------- 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/packages/chat-debug-view/src/parts/HandleEventRowClick/HandleEventRowClick.ts b/packages/chat-debug-view/src/parts/HandleEventRowClick/HandleEventRowClick.ts index ea7daae9..bfd99115 100644 --- a/packages/chat-debug-view/src/parts/HandleEventRowClick/HandleEventRowClick.ts +++ b/packages/chat-debug-view/src/parts/HandleEventRowClick/HandleEventRowClick.ts @@ -1,16 +1,19 @@ +import type * as LoadSelectedEvent from '../LoadSelectedEvent/LoadSelectedEvent.ts' import type { ChatDebugViewState } from '../State/ChatDebugViewState.ts' -import * as LoadSelectedEvent from '../LoadSelectedEvent/LoadSelectedEvent.ts' import { selectEventAtIndex } from '../SelectEventAtIndex/SelectEventAtIndex.ts' -export const handleEventRowClickDependencies = { - loadSelectedEvent: LoadSelectedEvent.loadSelectedEvent, -} +type LoadSelectedEventFn = typeof LoadSelectedEvent.loadSelectedEvent const isPrimaryButton = (button: number): boolean => { return button === 0 } -export const handleEventRowClick = async (state: ChatDebugViewState, index: string | number, button: number = 0): Promise => { +export const handleEventRowClick = async ( + state: ChatDebugViewState, + index: string | number, + button: number = 0, + loadSelectedEvent?: LoadSelectedEventFn, +): Promise => { const actual = typeof index === 'string' ? Number.parseInt(index, 10) : index if (!isPrimaryButton(button)) { return state @@ -18,5 +21,5 @@ export const handleEventRowClick = async (state: ChatDebugViewState, index: stri if (actual === -1) { return state } - return selectEventAtIndex(state, actual, handleEventRowClickDependencies) + return selectEventAtIndex(state, actual, loadSelectedEvent) } diff --git a/packages/chat-debug-view/src/parts/HandleEventRowClickAt/HandleEventRowClickAt.ts b/packages/chat-debug-view/src/parts/HandleEventRowClickAt/HandleEventRowClickAt.ts index 457fe421..28775353 100644 --- a/packages/chat-debug-view/src/parts/HandleEventRowClickAt/HandleEventRowClickAt.ts +++ b/packages/chat-debug-view/src/parts/HandleEventRowClickAt/HandleEventRowClickAt.ts @@ -1,13 +1,17 @@ +import type * as LoadSelectedEvent from '../LoadSelectedEvent/LoadSelectedEvent.ts' import type { ChatDebugViewState } from '../State/ChatDebugViewState.ts' import { getTableBodyEventIndex } from '../GetTableBodyEventIndex/GetTableBodyEventIndex.ts' import { handleEventRowClick } from '../HandleEventRowClick/HandleEventRowClick.ts' +type LoadSelectedEventFn = typeof LoadSelectedEvent.loadSelectedEvent + export const handleEventRowClickAt = async ( state: ChatDebugViewState, eventX: number, eventY: number, button: number = 0, + loadSelectedEvent?: LoadSelectedEventFn, ): Promise => { const selectedEventIndex = getTableBodyEventIndex(state, eventX, eventY) - return handleEventRowClick(state, selectedEventIndex, button) + return handleEventRowClick(state, selectedEventIndex, button, loadSelectedEvent) } diff --git a/packages/chat-debug-view/src/parts/SelectEventAtIndex/SelectEventAtIndex.ts b/packages/chat-debug-view/src/parts/SelectEventAtIndex/SelectEventAtIndex.ts index ae17fb2d..dd5fb050 100644 --- a/packages/chat-debug-view/src/parts/SelectEventAtIndex/SelectEventAtIndex.ts +++ b/packages/chat-debug-view/src/parts/SelectEventAtIndex/SelectEventAtIndex.ts @@ -8,20 +8,14 @@ import { mergeSelectedEventDetails } from '../MergeSelectedEventDetails/MergeSel import { withSelectedEventVisible } from '../VirtualTable/VirtualTable.ts' import { withPreparedSelectedEventPreview } from '../WithPreparedSelectedEventPreview/WithPreparedSelectedEventPreview.ts' -export interface SelectEventAtIndexDependencies { - readonly loadSelectedEvent: typeof LoadSelectedEvent.loadSelectedEvent -} - -export const selectEventAtIndexDependencies: SelectEventAtIndexDependencies = { - loadSelectedEvent: LoadSelectedEvent.loadSelectedEvent, -} +type LoadSelectedEventFn = typeof LoadSelectedEvent.loadSelectedEvent export const getCurrentEvents = (state: ChatDebugViewState): readonly ChatViewEvent[] => getSharedCurrentEvents(state) export const selectEventAtIndex = async ( state: ChatDebugViewState, selectedEventIndex: number, - dependencies: SelectEventAtIndexDependencies = selectEventAtIndexDependencies, + loadSelectedEvent: LoadSelectedEventFn = LoadSelectedEvent.loadSelectedEvent, ): Promise => { const { databaseName, dataBaseVersion, detailTabs, eventStoreName, sessionId, sessionIdIndexName } = state const selectedDetailTab = getSelectedDetailTab(detailTabs) @@ -43,7 +37,7 @@ export const selectEventAtIndex = async ( selectedEventIndex, } } - const selectedEventDetails = await dependencies.loadSelectedEvent( + const selectedEventDetails = await loadSelectedEvent( databaseName, dataBaseVersion, eventStoreName, diff --git a/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts b/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts index 74ec789e..fe1e82a0 100644 --- a/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts +++ b/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts @@ -1,13 +1,15 @@ import { afterEach, expect, jest, test } from '@jest/globals' import type { ChatDebugViewState } from '../src/parts/State/ChatDebugViewState.ts' +import type * as LoadSelectedEvent from '../src/parts/LoadSelectedEvent/LoadSelectedEvent.ts' import { createDetailTabs } from '../src/parts/CreateDetailTabs/CreateDetailTabs.ts' import { getSelectedDetailTab } from '../src/parts/GetSelectedDetailTab/GetSelectedDetailTab.ts' -import { handleEventRowClickDependencies } from '../src/parts/HandleEventRowClick/HandleEventRowClick.ts' import { handleEventRowClickAt } from '../src/parts/HandleEventRowClickAt/HandleEventRowClickAt.ts' import { hasDetailTab } from '../src/parts/HasDetailTab/HasDetailTab.ts' import { createDefaultState } from '../src/parts/State/CreateDefaultState.ts' import { applyVirtualTableState } from '../src/parts/VirtualTable/VirtualTable.ts' +type LoadSelectedEventFn = typeof LoadSelectedEvent.loadSelectedEvent + const tableClientX = 30 const row0ClientY = 180 const row1ClientY = 197 @@ -30,7 +32,7 @@ afterEach(() => { }) test('handleEventRowClick should select the clicked event row and load details', async () => { - const loadSelectedEventSpy = jest.spyOn(handleEventRowClickDependencies, 'loadSelectedEvent').mockResolvedValue({ + const loadSelectedEvent = jest.fn().mockResolvedValue({ detail: 'value', eventId: 3, type: 'request', @@ -61,7 +63,7 @@ test('handleEventRowClick should select the clicked event row and load details', ], sessionId: 'session-1', }) - const result = await handleEventRowClickAt(state, tableClientX, row2ClientY, 0) + const result = await handleEventRowClickAt(state, tableClientX, row2ClientY, 0, loadSelectedEvent) expect(result.selectedEventIndex).toBe(2) expect(result.selectedEvent).toEqual({ @@ -72,7 +74,7 @@ test('handleEventRowClick should select the clicked event row and load details', startTime: '2026-03-08T00:00:02.000Z', type: 'request', }) - expect(loadSelectedEventSpy).toHaveBeenCalledWith('lvce-chat-view-sessions', 2, 'chat-view-events', 'session-1', 'sessionId', 3, 'request') + expect(loadSelectedEvent).toHaveBeenCalledWith('lvce-chat-view-sessions', 2, 'chat-view-events', 'session-1', 'sessionId', 3, 'request') }) test('handleEventRowClick should ignore clicks outside the table body', async () => { @@ -127,7 +129,7 @@ test('handleEventRowClick should fall back to the in-memory event when it has no }) test('handleEventRowClick should fall back to the selected list event when loading details returns null', async () => { - jest.spyOn(handleEventRowClickDependencies, 'loadSelectedEvent').mockResolvedValue(null) + const loadSelectedEvent = jest.fn().mockResolvedValue(null) const state = createClickableState({ events: [ { @@ -141,7 +143,7 @@ test('handleEventRowClick should fall back to the selected list event when loadi sessionId: 'session-1', }) - const result = await handleEventRowClickAt(state, tableClientX, row0ClientY, 0) + const result = await handleEventRowClickAt(state, tableClientX, row0ClientY, 0, loadSelectedEvent) expect(result.selectedEventIndex).toBe(0) expect(result.selectedEventId).toBe(1) @@ -155,7 +157,7 @@ test('handleEventRowClick should fall back to the selected list event when loadi }) test('handleEventRowClick should preserve selected detail tab when switching rows', async () => { - jest.spyOn(handleEventRowClickDependencies, 'loadSelectedEvent').mockResolvedValue({ + const loadSelectedEvent = jest.fn().mockResolvedValue({ detail: 'preview', eventId: 2, type: 'response', @@ -177,7 +179,7 @@ test('handleEventRowClick should preserve selected detail tab when switching row sessionId: 'session-1', }) - const result = await handleEventRowClickAt(state, tableClientX, row1ClientY, 0) + const result = await handleEventRowClickAt(state, tableClientX, row1ClientY, 0, loadSelectedEvent) expect(getSelectedDetailTab(result.detailTabs)).toBe('preview') expect(result.selectedEventIndex).toBe(1) @@ -190,7 +192,7 @@ test('handleEventRowClick should preserve selected detail tab when switching row }) test('handleEventRowClick should fall back to response and hide timing when the selected event has no timing details', async () => { - jest.spyOn(handleEventRowClickDependencies, 'loadSelectedEvent').mockResolvedValue({ + const loadSelectedEvent = jest.fn().mockResolvedValue({ detail: 'preview', eventId: 2, type: 'chat-message-added', @@ -214,7 +216,7 @@ test('handleEventRowClick should fall back to response and hide timing when the sessionId: 'session-1', }) - const result = await handleEventRowClickAt(state, tableClientX, row1ClientY, 0) + const result = await handleEventRowClickAt(state, tableClientX, row1ClientY, 0, loadSelectedEvent) expect(getSelectedDetailTab(result.detailTabs)).toBe('response') expect(hasDetailTab(result.detailTabs, 'timing')).toBe(false) diff --git a/packages/chat-debug-view/test/SelectEventAtIndex.test.ts b/packages/chat-debug-view/test/SelectEventAtIndex.test.ts index de95accd..8ea75090 100644 --- a/packages/chat-debug-view/test/SelectEventAtIndex.test.ts +++ b/packages/chat-debug-view/test/SelectEventAtIndex.test.ts @@ -19,9 +19,7 @@ test('selectEventAtIndex should clear the selected event when the index is out o ], } - const result = await selectEventAtIndex(state, 3, { - loadSelectedEvent, - }) + const result = await selectEventAtIndex(state, 3, loadSelectedEvent) expect(result).toEqual({ ...state, @@ -44,9 +42,7 @@ test('selectEventAtIndex should keep the event selected when it has no numeric e events: [invalidEvent], } - const result = await selectEventAtIndex(state, 0, { - loadSelectedEvent, - }) + const result = await selectEventAtIndex(state, 0, loadSelectedEvent) expect(result).toEqual({ ...state, @@ -92,9 +88,7 @@ test('selectEventAtIndex should preserve merged ai request and response details' sessionId: 'session-1', } - const result = await selectEventAtIndex(state, 0, { - loadSelectedEvent, - }) + const result = await selectEventAtIndex(state, 0, loadSelectedEvent) expect(result.selectedEvent).toEqual( expect.objectContaining({ From e889c710dd9cfc0049e270e504a228ad389f404d Mon Sep 17 00:00:00 2001 From: Le Vivilet Date: Sun, 10 May 2026 22:03:12 +0200 Subject: [PATCH 2/2] fixfix --- packages/chat-debug-view/test/HandleEventRowClickAt.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts b/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts index fe1e82a0..961fcd84 100644 --- a/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts +++ b/packages/chat-debug-view/test/HandleEventRowClickAt.test.ts @@ -1,6 +1,6 @@ import { afterEach, expect, jest, test } from '@jest/globals' -import type { ChatDebugViewState } from '../src/parts/State/ChatDebugViewState.ts' import type * as LoadSelectedEvent from '../src/parts/LoadSelectedEvent/LoadSelectedEvent.ts' +import type { ChatDebugViewState } from '../src/parts/State/ChatDebugViewState.ts' import { createDetailTabs } from '../src/parts/CreateDetailTabs/CreateDetailTabs.ts' import { getSelectedDetailTab } from '../src/parts/GetSelectedDetailTab/GetSelectedDetailTab.ts' import { handleEventRowClickAt } from '../src/parts/HandleEventRowClickAt/HandleEventRowClickAt.ts'