@lvce-editor/chat-debug-view 5.3.0 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1171,14 +1171,414 @@ const diff2 = uid => {
1171
1171
  return diff(oldState, newState);
1172
1172
  };
1173
1173
 
1174
+ const handleCloseDetails = state => {
1175
+ return {
1176
+ ...state,
1177
+ selectedEvent: null,
1178
+ selectedEventId: null,
1179
+ selectedEventIndex: null
1180
+ };
1181
+ };
1182
+
1174
1183
  const handleDetailsContextMenu = state => {
1175
1184
  return state;
1176
1185
  };
1177
1186
 
1187
+ const handleDetailTab = (state, value) => {
1188
+ if (!isDetailTab(value)) {
1189
+ return state;
1190
+ }
1191
+ return {
1192
+ ...state,
1193
+ selectedDetailTab: value
1194
+ };
1195
+ };
1196
+
1197
+ const hasMatchingToolName$1 = (startedEvent, finishedEvent) => {
1198
+ if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
1199
+ return startedEvent.toolName === finishedEvent.toolName;
1200
+ }
1201
+ return true;
1202
+ };
1203
+
1204
+ const isMatchingToolExecutionPair = (startedEvent, finishedEvent) => {
1205
+ return startedEvent.sessionId === finishedEvent.sessionId && hasMatchingToolName$1(startedEvent, finishedEvent);
1206
+ };
1207
+
1208
+ const startedEventType$1 = 'tool-execution-started';
1209
+ const finishedEventType$1 = 'tool-execution-finished';
1210
+ const mergedEventType = 'tool-execution';
1211
+
1212
+ const isToolExecutionFinishedEvent = event => {
1213
+ return event.type === finishedEventType$1;
1214
+ };
1215
+
1216
+ const isToolExecutionStartedEvent = event => {
1217
+ return event.type === startedEventType$1;
1218
+ };
1219
+
1220
+ const getTimestamp$1 = value => {
1221
+ return typeof value === 'string' || typeof value === 'number' ? value : undefined;
1222
+ };
1223
+
1224
+ const getEndedTimestamp = event => {
1225
+ return getTimestamp$1(event.ended) ?? getTimestamp$1(event.endTime) ?? getTimestamp$1(event.endTimestamp) ?? getTimestamp$1(event.timestamp);
1226
+ };
1227
+
1228
+ const eventStableIds = new WeakMap();
1229
+ const eventStableIdState = {
1230
+ nextStableEventId: 1
1231
+ };
1232
+
1233
+ const getOrCreateStableEventId = event => {
1234
+ const existingStableEventId = eventStableIds.get(event);
1235
+ if (existingStableEventId) {
1236
+ return existingStableEventId;
1237
+ }
1238
+ const stableEventId = `event-${eventStableIdState.nextStableEventId++}`;
1239
+ eventStableIds.set(event, stableEventId);
1240
+ return stableEventId;
1241
+ };
1242
+
1243
+ const getStartedTimestamp = event => {
1244
+ return getTimestamp$1(event.started) ?? getTimestamp$1(event.startTime) ?? getTimestamp$1(event.startTimestamp) ?? getTimestamp$1(event.timestamp);
1245
+ };
1246
+
1247
+ const setStableEventId = (event, stableEventId) => {
1248
+ eventStableIds.set(event, stableEventId);
1249
+ };
1250
+
1251
+ const mergeToolExecutionEvents$1 = (startedEvent, finishedEvent) => {
1252
+ const ended = getEndedTimestamp(finishedEvent);
1253
+ const {
1254
+ eventId
1255
+ } = startedEvent;
1256
+ const started = getStartedTimestamp(startedEvent);
1257
+ const mergedEvent = {
1258
+ ...startedEvent,
1259
+ ...finishedEvent,
1260
+ ...(ended === undefined ? {} : {
1261
+ ended
1262
+ }),
1263
+ ...(eventId === undefined ? {} : {
1264
+ eventId
1265
+ }),
1266
+ ...(started === undefined ? {} : {
1267
+ started
1268
+ }),
1269
+ type: mergedEventType
1270
+ };
1271
+ const stableEventId = `${getOrCreateStableEventId(startedEvent)}:${getOrCreateStableEventId(finishedEvent)}`;
1272
+ setStableEventId(mergedEvent, stableEventId);
1273
+ return mergedEvent;
1274
+ };
1275
+
1276
+ const getStableEventId = event => {
1277
+ return getOrCreateStableEventId(event);
1278
+ };
1279
+
1280
+ const collapseToolExecutionEvents = events => {
1281
+ const collapsedEvents = [];
1282
+ for (let i = 0; i < events.length; i++) {
1283
+ const event = events[i];
1284
+ if (isToolExecutionStartedEvent(event)) {
1285
+ const nextEvent = events[i + 1];
1286
+ if (nextEvent && isToolExecutionFinishedEvent(nextEvent) && isMatchingToolExecutionPair(event, nextEvent)) {
1287
+ collapsedEvents.push(mergeToolExecutionEvents$1(event, nextEvent));
1288
+ i++;
1289
+ continue;
1290
+ }
1291
+ }
1292
+ collapsedEvents.push(event);
1293
+ }
1294
+ return collapsedEvents;
1295
+ };
1296
+
1297
+ const getVisibleEvents = (events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
1298
+ return events.filter(event => {
1299
+ if (!showInputEvents && event.type === 'handle-input') {
1300
+ return false;
1301
+ }
1302
+ if (!showResponsePartEvents && event.type === 'sse-response-part') {
1303
+ return false;
1304
+ }
1305
+ if (!showEventStreamFinishedEvents && event.type === 'event-stream-finished') {
1306
+ return false;
1307
+ }
1308
+ // hide session creation events by default — not useful in the debug view
1309
+ if (event.type === 'chat-session-created') {
1310
+ return false;
1311
+ }
1312
+ return true;
1313
+ });
1314
+ };
1315
+
1316
+ const isNetworkEvent = event => {
1317
+ const normalizedType = event.type.toLowerCase();
1318
+ return normalizedType === 'request' || normalizedType === 'response' || normalizedType === 'handle-response' || normalizedType.includes('fetch') || normalizedType.includes('xhr');
1319
+ };
1320
+
1321
+ const isStreamEvent = event => {
1322
+ return event.type === 'sse-response-part' || event.type === 'event-stream-finished';
1323
+ };
1324
+
1325
+ const toolEventTypePrefix = 'tool-execution';
1326
+ const isToolEvent = event => {
1327
+ return event.type.startsWith(toolEventTypePrefix);
1328
+ };
1329
+
1330
+ const isUiEvent = event => {
1331
+ return event.type.startsWith('handle-') && event.type !== 'handle-response';
1332
+ };
1333
+
1334
+ const matchesEventCategoryFilter = (event, eventCategoryFilter) => {
1335
+ switch (eventCategoryFilter) {
1336
+ case Network:
1337
+ return isNetworkEvent(event);
1338
+ case Stream:
1339
+ return isStreamEvent(event);
1340
+ case Tools:
1341
+ return isToolEvent(event);
1342
+ case Ui:
1343
+ return isUiEvent(event);
1344
+ default:
1345
+ return true;
1346
+ }
1347
+ };
1348
+
1349
+ const getFilteredEvents = (events, filterValue, eventCategoryFilter, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
1350
+ const visibleEvents = getVisibleEvents(events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents);
1351
+ const collapsedEvents = collapseToolExecutionEvents(visibleEvents);
1352
+ const parsedFilter = parseFilterValue(filterValue);
1353
+ const activeEventCategoryFilter = parsedFilter.eventCategoryFilter === All ? eventCategoryFilter : parsedFilter.eventCategoryFilter;
1354
+ const filteredByCategory = collapsedEvents.filter(event => matchesEventCategoryFilter(event, activeEventCategoryFilter));
1355
+ const {
1356
+ filterText
1357
+ } = parsedFilter;
1358
+ if (!filterText) {
1359
+ return filteredByCategory;
1360
+ }
1361
+ return filteredByCategory.filter(event => JSON.stringify(event).toLowerCase().includes(filterText));
1362
+ };
1363
+
1364
+ const toTimeNumber = value => {
1365
+ if (typeof value === 'number' && Number.isFinite(value)) {
1366
+ return value;
1367
+ }
1368
+ if (typeof value === 'string') {
1369
+ const timestamp = Date.parse(value);
1370
+ if (!Number.isNaN(timestamp)) {
1371
+ return timestamp;
1372
+ }
1373
+ }
1374
+ return undefined;
1375
+ };
1376
+
1377
+ const getEventTime = event => {
1378
+ return toTimeNumber(event.started ?? event.startTime ?? event.startTimestamp ?? event.timestamp);
1379
+ };
1380
+
1381
+ const maxBarUnits = 8;
1382
+ const parseTimelineSeconds = value => {
1383
+ const trimmed = value.trim();
1384
+ if (!trimmed) {
1385
+ return undefined;
1386
+ }
1387
+ const parsed = Number.parseFloat(trimmed);
1388
+ if (!Number.isFinite(parsed) || parsed < 0) {
1389
+ return undefined;
1390
+ }
1391
+ return parsed;
1392
+ };
1393
+ const roundSeconds = value => {
1394
+ return Number(value.toFixed(3));
1395
+ };
1396
+ const getEventsWithTime = events => {
1397
+ return events.flatMap(event => {
1398
+ const time = getEventTime(event);
1399
+ if (time === undefined) {
1400
+ return [];
1401
+ }
1402
+ return [{
1403
+ event,
1404
+ time
1405
+ }];
1406
+ });
1407
+ };
1408
+ const getTimelineDurationSeconds = events => {
1409
+ const eventsWithTime = getEventsWithTime(events);
1410
+ if (eventsWithTime.length === 0) {
1411
+ return 0;
1412
+ }
1413
+ const baseTime = eventsWithTime[0].time;
1414
+ const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
1415
+ return roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
1416
+ };
1417
+ const getSelectionPercent = (value, durationSeconds) => {
1418
+ if (durationSeconds <= 0) {
1419
+ return 0;
1420
+ }
1421
+ return Number((value / durationSeconds * 100).toFixed(3));
1422
+ };
1423
+ const getNormalizedRange = (durationSeconds, startValue, endValue) => {
1424
+ const parsedStart = parseTimelineSeconds(startValue);
1425
+ const parsedEnd = parseTimelineSeconds(endValue);
1426
+ if (parsedStart === undefined && parsedEnd === undefined) {
1427
+ return {
1428
+ endSeconds: null,
1429
+ hasSelection: false,
1430
+ startSeconds: null
1431
+ };
1432
+ }
1433
+ const rawStart = parsedStart ?? 0;
1434
+ const rawEnd = parsedEnd ?? durationSeconds;
1435
+ const normalizedStart = Math.max(0, Math.min(durationSeconds, Math.min(rawStart, rawEnd)));
1436
+ const normalizedEnd = Math.max(0, Math.min(durationSeconds, Math.max(rawStart, rawEnd)));
1437
+ return {
1438
+ endSeconds: roundSeconds(normalizedEnd),
1439
+ hasSelection: true,
1440
+ startSeconds: roundSeconds(normalizedStart)
1441
+ };
1442
+ };
1443
+ const filterEventsByTimelineRange = (events, startValue, endValue) => {
1444
+ const eventsWithTime = getEventsWithTime(events);
1445
+ if (eventsWithTime.length === 0) {
1446
+ return events;
1447
+ }
1448
+ const baseTime = eventsWithTime[0].time;
1449
+ const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
1450
+ const durationSeconds = roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
1451
+ const range = getNormalizedRange(durationSeconds, startValue, endValue);
1452
+ if (!range.hasSelection || range.startSeconds === null || range.endSeconds === null) {
1453
+ return events;
1454
+ }
1455
+ const startTime = baseTime + range.startSeconds * 1000;
1456
+ const endTime = baseTime + range.endSeconds * 1000;
1457
+ return eventsWithTime.filter(item => item.time >= startTime && item.time <= endTime).map(item => item.event);
1458
+ };
1459
+ const getTimelineInfo = (events, startValue, endValue) => {
1460
+ const eventsWithTime = getEventsWithTime(events);
1461
+ if (eventsWithTime.length === 0) {
1462
+ return {
1463
+ buckets: [],
1464
+ durationSeconds: 0,
1465
+ endSeconds: null,
1466
+ hasSelection: false,
1467
+ selectionEndPercent: null,
1468
+ selectionStartPercent: null,
1469
+ startSeconds: null
1470
+ };
1471
+ }
1472
+ const baseTime = eventsWithTime[0].time;
1473
+ const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
1474
+ const durationMs = Math.max(0, lastTime - baseTime);
1475
+ const durationSeconds = roundSeconds(durationMs / 1000);
1476
+ const range = getNormalizedRange(durationSeconds, startValue, endValue);
1477
+ const bucketCount = durationSeconds === 0 ? 1 : Math.max(12, Math.min(48, Math.ceil(durationSeconds)));
1478
+ const bucketDurationMs = durationMs === 0 ? 1000 : durationMs / bucketCount;
1479
+ const counts = Array.from({
1480
+ length: bucketCount
1481
+ }).fill(0);
1482
+ for (const item of eventsWithTime) {
1483
+ const offsetMs = item.time - baseTime;
1484
+ const index = durationMs === 0 ? 0 : Math.min(bucketCount - 1, Math.floor(offsetMs / durationMs * bucketCount));
1485
+ counts[index] += 1;
1486
+ }
1487
+ const maxCount = Math.max(...counts);
1488
+ const selectionStartPercent = range.hasSelection && range.startSeconds !== null ? getSelectionPercent(range.startSeconds, durationSeconds) : null;
1489
+ const selectionEndPercent = range.hasSelection && range.endSeconds !== null ? getSelectionPercent(range.endSeconds, durationSeconds) : null;
1490
+ const buckets = counts.map((count, index) => {
1491
+ const bucketStartMs = index * bucketDurationMs;
1492
+ const bucketEndMs = index === bucketCount - 1 ? durationMs : (index + 1) * bucketDurationMs;
1493
+ const hasSelection = range.hasSelection && range.startSeconds !== null && range.endSeconds !== null;
1494
+ const selectionStartMs = hasSelection ? range.startSeconds * 1000 : 0;
1495
+ const selectionEndMs = hasSelection ? range.endSeconds * 1000 : 0;
1496
+ return {
1497
+ count,
1498
+ endSeconds: roundSeconds(bucketEndMs / 1000),
1499
+ isSelected: hasSelection && bucketEndMs >= selectionStartMs && bucketStartMs <= selectionEndMs,
1500
+ startSeconds: roundSeconds(bucketStartMs / 1000),
1501
+ unitCount: count === 0 ? 0 : Math.max(1, Math.round(count / maxCount * maxBarUnits))
1502
+ };
1503
+ });
1504
+ return {
1505
+ buckets,
1506
+ durationSeconds,
1507
+ endSeconds: range.endSeconds,
1508
+ hasSelection: range.hasSelection,
1509
+ selectionEndPercent,
1510
+ selectionStartPercent,
1511
+ startSeconds: range.startSeconds
1512
+ };
1513
+ };
1514
+
1515
+ const getCurrentEvents$3 = state => {
1516
+ const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
1517
+ return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
1518
+ };
1519
+ const getEventIndexByStableId$1 = (events, event) => {
1520
+ const stableEventId = getStableEventId(event);
1521
+ return events.findIndex(candidate => getStableEventId(candidate) === stableEventId);
1522
+ };
1523
+ const getSelectedEventIndex$1 = state => {
1524
+ const {
1525
+ selectedEventIndex
1526
+ } = state;
1527
+ if (selectedEventIndex === null) {
1528
+ return null;
1529
+ }
1530
+ const filteredEvents = getCurrentEvents$3(state);
1531
+ const selectedEvent = filteredEvents[selectedEventIndex];
1532
+ if (!selectedEvent) {
1533
+ return null;
1534
+ }
1535
+ const newIndex = getEventIndexByStableId$1(filteredEvents, selectedEvent);
1536
+ if (newIndex === -1) {
1537
+ return null;
1538
+ }
1539
+ return newIndex;
1540
+ };
1541
+ const getPreservedSelectedEventIndex$1 = (oldState, newState) => {
1542
+ const {
1543
+ selectedEventIndex
1544
+ } = oldState;
1545
+ if (selectedEventIndex === null) {
1546
+ return null;
1547
+ }
1548
+ const oldFilteredEvents = getCurrentEvents$3(oldState);
1549
+ const selectedEvent = oldFilteredEvents[selectedEventIndex];
1550
+ if (!selectedEvent) {
1551
+ return null;
1552
+ }
1553
+ const newFilteredEvents = getCurrentEvents$3(newState);
1554
+ const newIndex = getEventIndexByStableId$1(newFilteredEvents, selectedEvent);
1555
+ if (newIndex === -1) {
1556
+ return null;
1557
+ }
1558
+ return newIndex;
1559
+ };
1560
+ const withPreservedSelection$1 = (state, nextState) => {
1561
+ const selectedEventIndex = getPreservedSelectedEventIndex$1(state, nextState);
1562
+ return {
1563
+ ...nextState,
1564
+ selectedEvent: selectedEventIndex === null ? null : state.selectedEvent,
1565
+ selectedEventId: selectedEventIndex === null ? null : state.selectedEventId,
1566
+ selectedEventIndex
1567
+ };
1568
+ };
1569
+
1570
+ const handleEventCategoryFilter = (state, value) => {
1571
+ const nextState = {
1572
+ ...state,
1573
+ eventCategoryFilter: value || All
1574
+ };
1575
+ return withPreservedSelection$1(state, nextState);
1576
+ };
1577
+
1178
1578
  // cspell:ignore IDBP
1179
1579
 
1180
- const startedEventType$1 = 'tool-execution-started';
1181
- const finishedEventType$1 = 'tool-execution-finished';
1580
+ const startedEventType = 'tool-execution-started';
1581
+ const finishedEventType = 'tool-execution-finished';
1182
1582
  const getRawEventBySessionIdAndEventId = async (store, sessionId, sessionIdIndexName, eventId) => {
1183
1583
  if (eventId < 1) {
1184
1584
  return undefined;
@@ -1200,18 +1600,18 @@ const getRawEventBySessionIdAndEventId = async (store, sessionId, sessionIdIndex
1200
1600
  const events = all.filter(event => event.sessionId === sessionId);
1201
1601
  return events[eventId - 1];
1202
1602
  };
1203
- const getTimestamp$1 = value => {
1603
+ const getTimestamp = value => {
1204
1604
  return typeof value === 'string' || typeof value === 'number' ? value : undefined;
1205
1605
  };
1206
- const hasMatchingToolName$1 = (startedEvent, finishedEvent) => {
1606
+ const hasMatchingToolName = (startedEvent, finishedEvent) => {
1207
1607
  if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
1208
1608
  return startedEvent.toolName === finishedEvent.toolName;
1209
1609
  }
1210
1610
  return true;
1211
1611
  };
1212
- const mergeToolExecutionEvents$1 = (startedEvent, finishedEvent, eventId) => {
1213
- const ended = getTimestamp$1(finishedEvent.ended) ?? getTimestamp$1(finishedEvent.endTime) ?? getTimestamp$1(finishedEvent.timestamp);
1214
- const started = getTimestamp$1(startedEvent.started) ?? getTimestamp$1(startedEvent.startTime) ?? getTimestamp$1(startedEvent.timestamp);
1612
+ const mergeToolExecutionEvents = (startedEvent, finishedEvent, eventId) => {
1613
+ const ended = getTimestamp(finishedEvent.ended) ?? getTimestamp(finishedEvent.endTime) ?? getTimestamp(finishedEvent.timestamp);
1614
+ const started = getTimestamp(startedEvent.started) ?? getTimestamp(startedEvent.startTime) ?? getTimestamp(startedEvent.timestamp);
1215
1615
  return {
1216
1616
  ...startedEvent,
1217
1617
  ...finishedEvent,
@@ -1236,20 +1636,20 @@ const getEventDetailsBySessionIdAndEventId = async (store, sessionId, sessionIdI
1236
1636
  eventId
1237
1637
  };
1238
1638
  }
1239
- if (event.type !== startedEventType$1) {
1639
+ if (event.type !== startedEventType) {
1240
1640
  return {
1241
1641
  ...event,
1242
1642
  eventId
1243
1643
  };
1244
1644
  }
1245
1645
  const nextEvent = await getRawEventBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId + 1);
1246
- if (!nextEvent || nextEvent.type !== finishedEventType$1 || nextEvent.sessionId !== sessionId || !hasMatchingToolName$1(event, nextEvent)) {
1646
+ if (!nextEvent || nextEvent.type !== finishedEventType || nextEvent.sessionId !== sessionId || !hasMatchingToolName(event, nextEvent)) {
1247
1647
  return {
1248
1648
  ...event,
1249
1649
  eventId
1250
1650
  };
1251
1651
  }
1252
- return mergeToolExecutionEvents$1(event, nextEvent, eventId);
1652
+ return mergeToolExecutionEvents(event, nextEvent, eventId);
1253
1653
  };
1254
1654
 
1255
1655
  const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
@@ -1473,381 +1873,63 @@ const cursorIteratorTraps = {
1473
1873
  return cachedFunc;
1474
1874
  }
1475
1875
  };
1476
- async function* iterate(...args) {
1477
- // tslint:disable-next-line:no-this-assignment
1478
- let cursor = this;
1479
- if (!(cursor instanceof IDBCursor)) {
1480
- cursor = await cursor.openCursor(...args);
1481
- }
1482
- if (!cursor) return;
1483
- cursor = cursor;
1484
- const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
1485
- ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
1486
- // Map this double-proxy back to the original, so other cursor methods work.
1487
- reverseTransformCache.set(proxiedCursor, unwrap(cursor));
1488
- while (cursor) {
1489
- yield proxiedCursor;
1490
- // If one of the advancing methods was not called, call continue().
1491
- cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
1492
- advanceResults.delete(proxiedCursor);
1493
- }
1494
- }
1495
- function isIteratorProp(target, prop) {
1496
- return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
1497
- }
1498
- replaceTraps(oldTraps => ({
1499
- ...oldTraps,
1500
- get(target, prop, receiver) {
1501
- if (isIteratorProp(target, prop)) return iterate;
1502
- return oldTraps.get(target, prop, receiver);
1503
- },
1504
- has(target, prop) {
1505
- return isIteratorProp(target, prop) || oldTraps.has(target, prop);
1506
- }
1507
- }));
1508
-
1509
- const openDatabaseDependencies = {
1510
- openDB: openDB
1511
- };
1512
- const openDatabase = async (databaseName, dataBaseVersion) => {
1513
- return openDatabaseDependencies.openDB(databaseName, dataBaseVersion);
1514
- };
1515
-
1516
- const loadSelectedEventDependencies = {
1517
- getEventDetailsBySessionIdAndEventId: getEventDetailsBySessionIdAndEventId,
1518
- openDatabase: openDatabase
1519
- };
1520
- const loadSelectedEvent = async (databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, eventId, type) => {
1521
- const database = await loadSelectedEventDependencies.openDatabase(databaseName, dataBaseVersion);
1522
- try {
1523
- if (!database.objectStoreNames.contains(eventStoreName)) {
1524
- return null;
1525
- }
1526
- const transaction = database.transaction(eventStoreName, 'readonly');
1527
- const store = transaction.objectStore(eventStoreName);
1528
- const event = await loadSelectedEventDependencies.getEventDetailsBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId, type);
1529
- return event ?? null;
1530
- } finally {
1531
- database.close();
1532
- }
1533
- };
1534
-
1535
- const hasMatchingToolName = (startedEvent, finishedEvent) => {
1536
- if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
1537
- return startedEvent.toolName === finishedEvent.toolName;
1538
- }
1539
- return true;
1540
- };
1541
-
1542
- const isMatchingToolExecutionPair = (startedEvent, finishedEvent) => {
1543
- return startedEvent.sessionId === finishedEvent.sessionId && hasMatchingToolName(startedEvent, finishedEvent);
1544
- };
1545
-
1546
- const startedEventType = 'tool-execution-started';
1547
- const finishedEventType = 'tool-execution-finished';
1548
- const mergedEventType = 'tool-execution';
1549
-
1550
- const isToolExecutionFinishedEvent = event => {
1551
- return event.type === finishedEventType;
1552
- };
1553
-
1554
- const isToolExecutionStartedEvent = event => {
1555
- return event.type === startedEventType;
1556
- };
1557
-
1558
- const getTimestamp = value => {
1559
- return typeof value === 'string' || typeof value === 'number' ? value : undefined;
1560
- };
1561
-
1562
- const getEndedTimestamp = event => {
1563
- return getTimestamp(event.ended) ?? getTimestamp(event.endTime) ?? getTimestamp(event.endTimestamp) ?? getTimestamp(event.timestamp);
1564
- };
1565
-
1566
- const eventStableIds = new WeakMap();
1567
- const eventStableIdState = {
1568
- nextStableEventId: 1
1569
- };
1570
-
1571
- const getOrCreateStableEventId = event => {
1572
- const existingStableEventId = eventStableIds.get(event);
1573
- if (existingStableEventId) {
1574
- return existingStableEventId;
1575
- }
1576
- const stableEventId = `event-${eventStableIdState.nextStableEventId++}`;
1577
- eventStableIds.set(event, stableEventId);
1578
- return stableEventId;
1579
- };
1580
-
1581
- const getStartedTimestamp = event => {
1582
- return getTimestamp(event.started) ?? getTimestamp(event.startTime) ?? getTimestamp(event.startTimestamp) ?? getTimestamp(event.timestamp);
1583
- };
1584
-
1585
- const setStableEventId = (event, stableEventId) => {
1586
- eventStableIds.set(event, stableEventId);
1587
- };
1588
-
1589
- const mergeToolExecutionEvents = (startedEvent, finishedEvent) => {
1590
- const ended = getEndedTimestamp(finishedEvent);
1591
- const {
1592
- eventId
1593
- } = startedEvent;
1594
- const started = getStartedTimestamp(startedEvent);
1595
- const mergedEvent = {
1596
- ...startedEvent,
1597
- ...finishedEvent,
1598
- ...(ended === undefined ? {} : {
1599
- ended
1600
- }),
1601
- ...(eventId === undefined ? {} : {
1602
- eventId
1603
- }),
1604
- ...(started === undefined ? {} : {
1605
- started
1606
- }),
1607
- type: mergedEventType
1608
- };
1609
- const stableEventId = `${getOrCreateStableEventId(startedEvent)}:${getOrCreateStableEventId(finishedEvent)}`;
1610
- setStableEventId(mergedEvent, stableEventId);
1611
- return mergedEvent;
1612
- };
1613
-
1614
- const getStableEventId = event => {
1615
- return getOrCreateStableEventId(event);
1616
- };
1617
-
1618
- const collapseToolExecutionEvents = events => {
1619
- const collapsedEvents = [];
1620
- for (let i = 0; i < events.length; i++) {
1621
- const event = events[i];
1622
- if (isToolExecutionStartedEvent(event)) {
1623
- const nextEvent = events[i + 1];
1624
- if (nextEvent && isToolExecutionFinishedEvent(nextEvent) && isMatchingToolExecutionPair(event, nextEvent)) {
1625
- collapsedEvents.push(mergeToolExecutionEvents(event, nextEvent));
1626
- i++;
1627
- continue;
1628
- }
1629
- }
1630
- collapsedEvents.push(event);
1631
- }
1632
- return collapsedEvents;
1633
- };
1634
-
1635
- const getVisibleEvents = (events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
1636
- return events.filter(event => {
1637
- if (!showInputEvents && event.type === 'handle-input') {
1638
- return false;
1639
- }
1640
- if (!showResponsePartEvents && event.type === 'sse-response-part') {
1641
- return false;
1642
- }
1643
- if (!showEventStreamFinishedEvents && event.type === 'event-stream-finished') {
1644
- return false;
1645
- }
1646
- // hide session creation events by default — not useful in the debug view
1647
- if (event.type === 'chat-session-created') {
1648
- return false;
1649
- }
1650
- return true;
1651
- });
1652
- };
1653
-
1654
- const isNetworkEvent = event => {
1655
- const normalizedType = event.type.toLowerCase();
1656
- return normalizedType === 'request' || normalizedType === 'response' || normalizedType === 'handle-response' || normalizedType.includes('fetch') || normalizedType.includes('xhr');
1657
- };
1658
-
1659
- const isStreamEvent = event => {
1660
- return event.type === 'sse-response-part' || event.type === 'event-stream-finished';
1661
- };
1662
-
1663
- const toolEventTypePrefix = 'tool-execution';
1664
- const isToolEvent = event => {
1665
- return event.type.startsWith(toolEventTypePrefix);
1666
- };
1667
-
1668
- const isUiEvent = event => {
1669
- return event.type.startsWith('handle-') && event.type !== 'handle-response';
1670
- };
1671
-
1672
- const matchesEventCategoryFilter = (event, eventCategoryFilter) => {
1673
- switch (eventCategoryFilter) {
1674
- case Network:
1675
- return isNetworkEvent(event);
1676
- case Stream:
1677
- return isStreamEvent(event);
1678
- case Tools:
1679
- return isToolEvent(event);
1680
- case Ui:
1681
- return isUiEvent(event);
1682
- default:
1683
- return true;
1684
- }
1685
- };
1686
-
1687
- const getFilteredEvents = (events, filterValue, eventCategoryFilter, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
1688
- const visibleEvents = getVisibleEvents(events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents);
1689
- const collapsedEvents = collapseToolExecutionEvents(visibleEvents);
1690
- const parsedFilter = parseFilterValue(filterValue);
1691
- const activeEventCategoryFilter = parsedFilter.eventCategoryFilter === All ? eventCategoryFilter : parsedFilter.eventCategoryFilter;
1692
- const filteredByCategory = collapsedEvents.filter(event => matchesEventCategoryFilter(event, activeEventCategoryFilter));
1693
- const {
1694
- filterText
1695
- } = parsedFilter;
1696
- if (!filterText) {
1697
- return filteredByCategory;
1876
+ async function* iterate(...args) {
1877
+ // tslint:disable-next-line:no-this-assignment
1878
+ let cursor = this;
1879
+ if (!(cursor instanceof IDBCursor)) {
1880
+ cursor = await cursor.openCursor(...args);
1698
1881
  }
1699
- return filteredByCategory.filter(event => JSON.stringify(event).toLowerCase().includes(filterText));
1700
- };
1701
-
1702
- const toTimeNumber = value => {
1703
- if (typeof value === 'number' && Number.isFinite(value)) {
1704
- return value;
1882
+ if (!cursor) return;
1883
+ cursor = cursor;
1884
+ const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
1885
+ ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
1886
+ // Map this double-proxy back to the original, so other cursor methods work.
1887
+ reverseTransformCache.set(proxiedCursor, unwrap(cursor));
1888
+ while (cursor) {
1889
+ yield proxiedCursor;
1890
+ // If one of the advancing methods was not called, call continue().
1891
+ cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
1892
+ advanceResults.delete(proxiedCursor);
1705
1893
  }
1706
- if (typeof value === 'string') {
1707
- const timestamp = Date.parse(value);
1708
- if (!Number.isNaN(timestamp)) {
1709
- return timestamp;
1710
- }
1894
+ }
1895
+ function isIteratorProp(target, prop) {
1896
+ return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
1897
+ }
1898
+ replaceTraps(oldTraps => ({
1899
+ ...oldTraps,
1900
+ get(target, prop, receiver) {
1901
+ if (isIteratorProp(target, prop)) return iterate;
1902
+ return oldTraps.get(target, prop, receiver);
1903
+ },
1904
+ has(target, prop) {
1905
+ return isIteratorProp(target, prop) || oldTraps.has(target, prop);
1711
1906
  }
1712
- return undefined;
1713
- };
1907
+ }));
1714
1908
 
1715
- const getEventTime = event => {
1716
- return toTimeNumber(event.started ?? event.startTime ?? event.startTimestamp ?? event.timestamp);
1909
+ const openDatabaseDependencies = {
1910
+ openDB: openDB
1717
1911
  };
1718
-
1719
- const maxBarUnits = 8;
1720
- const parseTimelineSeconds = value => {
1721
- const trimmed = value.trim();
1722
- if (!trimmed) {
1723
- return undefined;
1724
- }
1725
- const parsed = Number.parseFloat(trimmed);
1726
- if (!Number.isFinite(parsed) || parsed < 0) {
1727
- return undefined;
1728
- }
1729
- return parsed;
1912
+ const openDatabase = async (databaseName, dataBaseVersion) => {
1913
+ return openDatabaseDependencies.openDB(databaseName, dataBaseVersion);
1730
1914
  };
1731
- const roundSeconds = value => {
1732
- return Number(value.toFixed(3));
1915
+
1916
+ const loadSelectedEventDependencies = {
1917
+ getEventDetailsBySessionIdAndEventId: getEventDetailsBySessionIdAndEventId,
1918
+ openDatabase: openDatabase
1733
1919
  };
1734
- const getEventsWithTime = events => {
1735
- return events.flatMap(event => {
1736
- const time = getEventTime(event);
1737
- if (time === undefined) {
1738
- return [];
1920
+ const loadSelectedEvent = async (databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, eventId, type) => {
1921
+ const database = await loadSelectedEventDependencies.openDatabase(databaseName, dataBaseVersion);
1922
+ try {
1923
+ if (!database.objectStoreNames.contains(eventStoreName)) {
1924
+ return null;
1739
1925
  }
1740
- return [{
1741
- event,
1742
- time
1743
- }];
1744
- });
1745
- };
1746
- const getTimelineDurationSeconds = events => {
1747
- const eventsWithTime = getEventsWithTime(events);
1748
- if (eventsWithTime.length === 0) {
1749
- return 0;
1750
- }
1751
- const baseTime = eventsWithTime[0].time;
1752
- const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
1753
- return roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
1754
- };
1755
- const getSelectionPercent = (value, durationSeconds) => {
1756
- if (durationSeconds <= 0) {
1757
- return 0;
1758
- }
1759
- return Number((value / durationSeconds * 100).toFixed(3));
1760
- };
1761
- const getNormalizedRange = (durationSeconds, startValue, endValue) => {
1762
- const parsedStart = parseTimelineSeconds(startValue);
1763
- const parsedEnd = parseTimelineSeconds(endValue);
1764
- if (parsedStart === undefined && parsedEnd === undefined) {
1765
- return {
1766
- endSeconds: null,
1767
- hasSelection: false,
1768
- startSeconds: null
1769
- };
1770
- }
1771
- const rawStart = parsedStart ?? 0;
1772
- const rawEnd = parsedEnd ?? durationSeconds;
1773
- const normalizedStart = Math.max(0, Math.min(durationSeconds, Math.min(rawStart, rawEnd)));
1774
- const normalizedEnd = Math.max(0, Math.min(durationSeconds, Math.max(rawStart, rawEnd)));
1775
- return {
1776
- endSeconds: roundSeconds(normalizedEnd),
1777
- hasSelection: true,
1778
- startSeconds: roundSeconds(normalizedStart)
1779
- };
1780
- };
1781
- const filterEventsByTimelineRange = (events, startValue, endValue) => {
1782
- const eventsWithTime = getEventsWithTime(events);
1783
- if (eventsWithTime.length === 0) {
1784
- return events;
1785
- }
1786
- const baseTime = eventsWithTime[0].time;
1787
- const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
1788
- const durationSeconds = roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
1789
- const range = getNormalizedRange(durationSeconds, startValue, endValue);
1790
- if (!range.hasSelection || range.startSeconds === null || range.endSeconds === null) {
1791
- return events;
1792
- }
1793
- const startTime = baseTime + range.startSeconds * 1000;
1794
- const endTime = baseTime + range.endSeconds * 1000;
1795
- return eventsWithTime.filter(item => item.time >= startTime && item.time <= endTime).map(item => item.event);
1796
- };
1797
- const getTimelineInfo = (events, startValue, endValue) => {
1798
- const eventsWithTime = getEventsWithTime(events);
1799
- if (eventsWithTime.length === 0) {
1800
- return {
1801
- buckets: [],
1802
- durationSeconds: 0,
1803
- endSeconds: null,
1804
- hasSelection: false,
1805
- selectionEndPercent: null,
1806
- selectionStartPercent: null,
1807
- startSeconds: null
1808
- };
1809
- }
1810
- const baseTime = eventsWithTime[0].time;
1811
- const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
1812
- const durationMs = Math.max(0, lastTime - baseTime);
1813
- const durationSeconds = roundSeconds(durationMs / 1000);
1814
- const range = getNormalizedRange(durationSeconds, startValue, endValue);
1815
- const bucketCount = durationSeconds === 0 ? 1 : Math.max(12, Math.min(48, Math.ceil(durationSeconds)));
1816
- const bucketDurationMs = durationMs === 0 ? 1000 : durationMs / bucketCount;
1817
- const counts = Array.from({
1818
- length: bucketCount
1819
- }).fill(0);
1820
- for (const item of eventsWithTime) {
1821
- const offsetMs = item.time - baseTime;
1822
- const index = durationMs === 0 ? 0 : Math.min(bucketCount - 1, Math.floor(offsetMs / durationMs * bucketCount));
1823
- counts[index] += 1;
1926
+ const transaction = database.transaction(eventStoreName, 'readonly');
1927
+ const store = transaction.objectStore(eventStoreName);
1928
+ const event = await loadSelectedEventDependencies.getEventDetailsBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId, type);
1929
+ return event ?? null;
1930
+ } finally {
1931
+ database.close();
1824
1932
  }
1825
- const maxCount = Math.max(...counts);
1826
- const selectionStartPercent = range.hasSelection && range.startSeconds !== null ? getSelectionPercent(range.startSeconds, durationSeconds) : null;
1827
- const selectionEndPercent = range.hasSelection && range.endSeconds !== null ? getSelectionPercent(range.endSeconds, durationSeconds) : null;
1828
- const buckets = counts.map((count, index) => {
1829
- const bucketStartMs = index * bucketDurationMs;
1830
- const bucketEndMs = index === bucketCount - 1 ? durationMs : (index + 1) * bucketDurationMs;
1831
- const hasSelection = range.hasSelection && range.startSeconds !== null && range.endSeconds !== null;
1832
- const selectionStartMs = hasSelection ? range.startSeconds * 1000 : 0;
1833
- const selectionEndMs = hasSelection ? range.endSeconds * 1000 : 0;
1834
- return {
1835
- count,
1836
- endSeconds: roundSeconds(bucketEndMs / 1000),
1837
- isSelected: hasSelection && bucketEndMs >= selectionStartMs && bucketStartMs <= selectionEndMs,
1838
- startSeconds: roundSeconds(bucketStartMs / 1000),
1839
- unitCount: count === 0 ? 0 : Math.max(1, Math.round(count / maxCount * maxBarUnits))
1840
- };
1841
- });
1842
- return {
1843
- buckets,
1844
- durationSeconds,
1845
- endSeconds: range.endSeconds,
1846
- hasSelection: range.hasSelection,
1847
- selectionEndPercent,
1848
- selectionStartPercent,
1849
- startSeconds: range.startSeconds
1850
- };
1851
1933
  };
1852
1934
 
1853
1935
  const getCurrentEvents$2 = state => {
@@ -1895,7 +1977,7 @@ const parseSelectedEventIndex$1 = value => {
1895
1977
  }
1896
1978
  return parsed;
1897
1979
  };
1898
- const handleEventRowClick = async (state, value, button) => {
1980
+ const handleEventRowClick = async (state, value, button = 0) => {
1899
1981
  if (!isPrimaryButton(button)) {
1900
1982
  return state;
1901
1983
  }
@@ -1931,7 +2013,7 @@ const getCurrentEvents$1 = state => {
1931
2013
  const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
1932
2014
  return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
1933
2015
  };
1934
- const parseTimelineRangePreset = value => {
2016
+ const parseTimelineRangePreset$1 = value => {
1935
2017
  if (!value) {
1936
2018
  return {
1937
2019
  timelineEndSeconds: '',
@@ -2074,7 +2156,7 @@ const handleInput = (state, name, value, checked) => {
2074
2156
  if (name === TimelineRangePreset) {
2075
2157
  const nextState = {
2076
2158
  ...state,
2077
- ...parseTimelineRangePreset(value)
2159
+ ...parseTimelineRangePreset$1(value)
2078
2160
  };
2079
2161
  return withPreservedSelection(state, nextState);
2080
2162
  }
@@ -2126,8 +2208,43 @@ const clearTimelineSelectionState = state => {
2126
2208
  };
2127
2209
  };
2128
2210
 
2211
+ const parseTimelineRangePreset = value => {
2212
+ if (!value) {
2213
+ return {
2214
+ timelineEndSeconds: '',
2215
+ timelineStartSeconds: ''
2216
+ };
2217
+ }
2218
+ const [timelineStartSeconds = '', timelineEndSeconds = ''] = value.split(':', 2);
2219
+ return {
2220
+ timelineEndSeconds,
2221
+ timelineStartSeconds
2222
+ };
2223
+ };
2224
+ const handleTimelineStartSeconds = (state, value) => {
2225
+ const nextState = {
2226
+ ...state,
2227
+ timelineStartSeconds: value
2228
+ };
2229
+ return withPreservedSelection$1(state, nextState);
2230
+ };
2231
+ const handleTimelineEndSeconds = (state, value) => {
2232
+ const nextState = {
2233
+ ...state,
2234
+ timelineEndSeconds: value
2235
+ };
2236
+ return withPreservedSelection$1(state, nextState);
2237
+ };
2238
+ const handleTimelineRangePreset = (state, value) => {
2239
+ const nextState = {
2240
+ ...state,
2241
+ ...parseTimelineRangePreset(value)
2242
+ };
2243
+ return withPreservedSelection$1(state, nextState);
2244
+ };
2245
+
2129
2246
  const handleTimelineDoubleClick = state => {
2130
- const nextState = handleInput(state, TimelineRangePreset, '', false);
2247
+ const nextState = handleTimelineRangePreset(state, '');
2131
2248
  return clearTimelineSelectionState(nextState);
2132
2249
  };
2133
2250
 
@@ -2217,10 +2334,44 @@ const handleTimelinePointerUp = (state, eventX) => {
2217
2334
  const focus = Number.parseFloat(focusSeconds);
2218
2335
  const startSeconds = formatTimelinePresetValue(Math.min(anchor, focus));
2219
2336
  const endSeconds = formatTimelinePresetValue(Math.max(anchor, focus));
2220
- const nextState = handleInput(state, TimelineRangePreset, `${startSeconds}:${endSeconds}`, false);
2337
+ const nextState = handleTimelineRangePreset(state, `${startSeconds}:${endSeconds}`);
2221
2338
  return clearTimelineSelectionState(nextState);
2222
2339
  };
2223
2340
 
2341
+ const handleUseDevtoolsLayout = (state, checked) => {
2342
+ const useDevtoolsLayout = getBoolean(checked);
2343
+ const selectedEventIndex = useDevtoolsLayout ? getSelectedEventIndex$1(state) : null;
2344
+ return {
2345
+ ...state,
2346
+ selectedEvent: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEvent : null,
2347
+ selectedEventId: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEventId : null,
2348
+ selectedEventIndex,
2349
+ useDevtoolsLayout
2350
+ };
2351
+ };
2352
+
2353
+ const handleShowEventStreamFinishedEvents = (state, checked) => {
2354
+ const nextState = {
2355
+ ...state,
2356
+ showEventStreamFinishedEvents: getBoolean(checked)
2357
+ };
2358
+ return withPreservedSelection$1(state, nextState);
2359
+ };
2360
+ const handleShowInputEvents = (state, checked) => {
2361
+ const nextState = {
2362
+ ...state,
2363
+ showInputEvents: getBoolean(checked)
2364
+ };
2365
+ return withPreservedSelection$1(state, nextState);
2366
+ };
2367
+ const handleShowResponsePartEvents = (state, checked) => {
2368
+ const nextState = {
2369
+ ...state,
2370
+ showResponsePartEvents: getBoolean(checked)
2371
+ };
2372
+ return withPreservedSelection$1(state, nextState);
2373
+ };
2374
+
2224
2375
  const getFailedToLoadMessage = sessionId => {
2225
2376
  return `Failed to load chat debug session "${sessionId}". Please try again.`;
2226
2377
  };
@@ -2588,7 +2739,6 @@ const Reference = 100;
2588
2739
 
2589
2740
  const ClientX = 'event.clientX';
2590
2741
  const ClientY = 'event.clientY';
2591
- const TargetChecked = 'event.target.checked';
2592
2742
  const TargetName = 'event.target.name';
2593
2743
  const TargetValue = 'event.target.value';
2594
2744
 
@@ -3715,9 +3865,9 @@ const getDebugErrorDom = errorMessage => {
3715
3865
  }, text(errorMessage)];
3716
3866
  };
3717
3867
 
3718
- const HandleInput = 4;
3868
+ const HandleEventCategoryFilter = 4;
3719
3869
  const HandleFilterInput = 5;
3720
- const HandleSimpleInput = 6;
3870
+ const HandleDetailTab = 6;
3721
3871
  const HandleEventRowClick = 7;
3722
3872
  const HandleHeaderContextMenu = 8;
3723
3873
  const HandleSashPointerDown = 9;
@@ -3730,6 +3880,8 @@ const HandleTimelinePointerMove = 15;
3730
3880
  const HandleTimelinePointerUp = 16;
3731
3881
  const HandleTimelineDoubleClick = 17;
3732
3882
  const HandleTableKeyDown = 18;
3883
+ const HandleTimelineRangePreset = 19;
3884
+ const HandleCloseDetails = 20;
3733
3885
 
3734
3886
  const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) => {
3735
3887
  if (useDevtoolsLayout) {
@@ -3857,8 +4009,8 @@ const getTabNodes = selectedDetailTab => {
3857
4009
  className: joinClassNames(ChatDebugViewDetailsTab, isSelected && ChatDebugViewDetailsTabSelected),
3858
4010
  id: getTabId(detailTab),
3859
4011
  name: DetailTab,
3860
- onChange: HandleSimpleInput,
3861
- onClick: HandleSimpleInput,
4012
+ onChange: HandleDetailTab,
4013
+ onClick: HandleDetailTab,
3862
4014
  role: 'tab',
3863
4015
  tabIndex: isSelected ? 0 : -1,
3864
4016
  type: Button,
@@ -3884,8 +4036,8 @@ const getDetailsDom = (previewEventNodes, responseEventNodes = previewEventNodes
3884
4036
  childCount: 0,
3885
4037
  className: ChatDebugViewDetailsClose,
3886
4038
  name: CloseDetails,
3887
- onChange: HandleSimpleInput,
3888
- onClick: HandleSimpleInput,
4039
+ onChange: HandleCloseDetails,
4040
+ onClick: HandleCloseDetails,
3889
4041
  type: Button,
3890
4042
  value: 'close'
3891
4043
  }, {
@@ -4316,7 +4468,7 @@ const getBucketDom = bucket => {
4316
4468
  className: ChatDebugViewTimelinePresetInput,
4317
4469
  inputType: 'radio',
4318
4470
  name: TimelineRangePreset,
4319
- onChange: HandleSimpleInput,
4471
+ onChange: HandleTimelineRangePreset,
4320
4472
  type: Input,
4321
4473
  value: presetValue
4322
4474
  }, {
@@ -4466,7 +4618,7 @@ const getQuickFilterNodes = (eventCategoryFilter, eventCategoryFilterOptions) =>
4466
4618
  className: ChatDebugViewQuickFilterInput,
4467
4619
  inputType: 'radio',
4468
4620
  name: EventCategoryFilter,
4469
- onChange: HandleInput,
4621
+ onChange: HandleEventCategoryFilter,
4470
4622
  type: Input,
4471
4623
  value: option.value
4472
4624
  }, text(option.label)];
@@ -4593,11 +4745,17 @@ const renderEventListeners = () => {
4593
4745
  name: HandleFilterInput,
4594
4746
  params: ['handleInput', TargetName, TargetValue]
4595
4747
  }, {
4596
- name: HandleInput,
4597
- params: ['handleInput', TargetName, TargetValue, TargetChecked]
4748
+ name: HandleEventCategoryFilter,
4749
+ params: ['handleEventCategoryFilter', TargetValue]
4598
4750
  }, {
4599
- name: HandleSimpleInput,
4600
- params: ['handleInput', TargetName, TargetValue]
4751
+ name: HandleDetailTab,
4752
+ params: ['handleDetailTab', TargetValue]
4753
+ }, {
4754
+ name: HandleTimelineRangePreset,
4755
+ params: ['handleTimelineRangePreset', TargetValue]
4756
+ }, {
4757
+ name: HandleCloseDetails,
4758
+ params: ['handleCloseDetails']
4601
4759
  }, {
4602
4760
  name: HandleSashPointerDown,
4603
4761
  params: ['handleSashPointerDown', ClientX, ClientY],
@@ -4694,8 +4852,11 @@ const setIndexedDbSupportForTest = supported => {
4694
4852
  return setIndexedDbSupportOverride(supported);
4695
4853
  };
4696
4854
 
4855
+ const setSessionIdDependencies = {
4856
+ listChatViewEvents: listChatViewEvents
4857
+ };
4697
4858
  const setSessionId = async (state, sessionId) => {
4698
- const result = await listChatViewEvents(sessionId, state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionIdIndexName);
4859
+ const result = await setSessionIdDependencies.listChatViewEvents(sessionId, state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionIdIndexName, state.indexedDbSupportOverride);
4699
4860
  if (result.type === 'not-supported') {
4700
4861
  return {
4701
4862
  ...state,
@@ -4704,6 +4865,7 @@ const setSessionId = async (state, sessionId) => {
4704
4865
  initial: false,
4705
4866
  selectedEvent: null,
4706
4867
  selectedEventId: null,
4868
+ selectedEventIndex: null,
4707
4869
  sessionId
4708
4870
  };
4709
4871
  }
@@ -4715,6 +4877,7 @@ const setSessionId = async (state, sessionId) => {
4715
4877
  initial: false,
4716
4878
  selectedEvent: null,
4717
4879
  selectedEventId: null,
4880
+ selectedEventIndex: null,
4718
4881
  sessionId
4719
4882
  };
4720
4883
  }
@@ -4728,6 +4891,7 @@ const setSessionId = async (state, sessionId) => {
4728
4891
  initial: false,
4729
4892
  selectedEvent: null,
4730
4893
  selectedEventId: null,
4894
+ selectedEventIndex: null,
4731
4895
  sessionId
4732
4896
  };
4733
4897
  };
@@ -4736,18 +4900,28 @@ const commandMap = {
4736
4900
  'ChatDebug.create': create,
4737
4901
  'ChatDebug.diff2': diff2,
4738
4902
  'ChatDebug.getCommandIds': getCommandIds,
4903
+ 'ChatDebug.handleCloseDetails': wrapCommand(handleCloseDetails),
4739
4904
  'ChatDebug.handleDetailsContextMenu': wrapCommand(handleDetailsContextMenu),
4905
+ 'ChatDebug.handleDetailTab': wrapCommand(handleDetailTab),
4906
+ 'ChatDebug.handleEventCategoryFilter': wrapCommand(handleEventCategoryFilter),
4740
4907
  'ChatDebug.handleEventRowClick': wrapCommand(handleEventRowClick),
4741
4908
  'ChatDebug.handleHeaderContextMenu': wrapCommand(handleHeaderContextMenu),
4742
4909
  'ChatDebug.handleInput': wrapCommand(handleInput),
4743
4910
  'ChatDebug.handleSashPointerDown': wrapCommand(handleSashPointerDown),
4744
4911
  'ChatDebug.handleSashPointerMove': wrapCommand(handleSashPointerMove),
4745
4912
  'ChatDebug.handleSashPointerUp': wrapCommand(handleSashPointerUp),
4913
+ 'ChatDebug.handleShowEventStreamFinishedEvents': wrapCommand(handleShowEventStreamFinishedEvents),
4914
+ 'ChatDebug.handleShowInputEvents': wrapCommand(handleShowInputEvents),
4915
+ 'ChatDebug.handleShowResponsePartEvents': wrapCommand(handleShowResponsePartEvents),
4746
4916
  'ChatDebug.handleTableBodyContextMenu': wrapCommand(handleTableBodyContextMenu),
4747
4917
  'ChatDebug.handleTimelineDoubleClick': wrapCommand(handleTimelineDoubleClick),
4918
+ 'ChatDebug.handleTimelineEndSeconds': wrapCommand(handleTimelineEndSeconds),
4748
4919
  'ChatDebug.handleTimelinePointerDown': wrapCommand(handleTimelinePointerDown),
4749
4920
  'ChatDebug.handleTimelinePointerMove': wrapCommand(handleTimelinePointerMove),
4750
4921
  'ChatDebug.handleTimelinePointerUp': wrapCommand(handleTimelinePointerUp),
4922
+ 'ChatDebug.handleTimelineRangePreset': wrapCommand(handleTimelineRangePreset),
4923
+ 'ChatDebug.handleTimelineStartSeconds': wrapCommand(handleTimelineStartSeconds),
4924
+ 'ChatDebug.handleUseDevtoolsLayout': wrapCommand(handleUseDevtoolsLayout),
4751
4925
  'ChatDebug.loadContent': wrapCommand(loadContent),
4752
4926
  'ChatDebug.loadContent2': wrapCommand(loadContent),
4753
4927
  'ChatDebug.refresh': wrapCommand(refresh),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-debug-view",
3
- "version": "5.3.0",
3
+ "version": "5.4.0",
4
4
  "description": "Chat Debug View Worker",
5
5
  "repository": {
6
6
  "type": "git",