@lvce-editor/chat-debug-view 5.5.0 → 7.0.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.
- package/dist/chatDebugViewWorkerMain.js +1113 -1883
- package/package.json +1 -1
|
@@ -54,6 +54,49 @@ class VError extends Error {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
class AssertionError extends Error {
|
|
58
|
+
constructor(message) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.name = 'AssertionError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const Object$1 = 1;
|
|
64
|
+
const Number$1 = 2;
|
|
65
|
+
const Array$1 = 3;
|
|
66
|
+
const String$1 = 4;
|
|
67
|
+
const Boolean$1 = 5;
|
|
68
|
+
const Function = 6;
|
|
69
|
+
const Null = 7;
|
|
70
|
+
const Unknown = 8;
|
|
71
|
+
const getType = value => {
|
|
72
|
+
switch (typeof value) {
|
|
73
|
+
case 'number':
|
|
74
|
+
return Number$1;
|
|
75
|
+
case 'function':
|
|
76
|
+
return Function;
|
|
77
|
+
case 'string':
|
|
78
|
+
return String$1;
|
|
79
|
+
case 'object':
|
|
80
|
+
if (value === null) {
|
|
81
|
+
return Null;
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(value)) {
|
|
84
|
+
return Array$1;
|
|
85
|
+
}
|
|
86
|
+
return Object$1;
|
|
87
|
+
case 'boolean':
|
|
88
|
+
return Boolean$1;
|
|
89
|
+
default:
|
|
90
|
+
return Unknown;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const number = value => {
|
|
94
|
+
const type = getType(value);
|
|
95
|
+
if (type !== Number$1) {
|
|
96
|
+
throw new AssertionError('expected value to be of type number');
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
57
100
|
const isMessagePort = value => {
|
|
58
101
|
return value && value instanceof MessagePort;
|
|
59
102
|
};
|
|
@@ -368,6 +411,100 @@ const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
|
368
411
|
listen: listen$6,
|
|
369
412
|
wrap: wrap$e
|
|
370
413
|
};
|
|
414
|
+
const addListener = (emitter, type, callback) => {
|
|
415
|
+
if ('addEventListener' in emitter) {
|
|
416
|
+
emitter.addEventListener(type, callback);
|
|
417
|
+
} else {
|
|
418
|
+
emitter.on(type, callback);
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
const removeListener = (emitter, type, callback) => {
|
|
422
|
+
if ('removeEventListener' in emitter) {
|
|
423
|
+
emitter.removeEventListener(type, callback);
|
|
424
|
+
} else {
|
|
425
|
+
emitter.off(type, callback);
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
const getFirstEvent = (eventEmitter, eventMap) => {
|
|
429
|
+
const {
|
|
430
|
+
promise,
|
|
431
|
+
resolve
|
|
432
|
+
} = Promise.withResolvers();
|
|
433
|
+
const listenerMap = Object.create(null);
|
|
434
|
+
const cleanup = value => {
|
|
435
|
+
for (const event of Object.keys(eventMap)) {
|
|
436
|
+
removeListener(eventEmitter, event, listenerMap[event]);
|
|
437
|
+
}
|
|
438
|
+
resolve(value);
|
|
439
|
+
};
|
|
440
|
+
for (const [event, type] of Object.entries(eventMap)) {
|
|
441
|
+
const listener = event => {
|
|
442
|
+
cleanup({
|
|
443
|
+
event,
|
|
444
|
+
type
|
|
445
|
+
});
|
|
446
|
+
};
|
|
447
|
+
addListener(eventEmitter, event, listener);
|
|
448
|
+
listenerMap[event] = listener;
|
|
449
|
+
}
|
|
450
|
+
return promise;
|
|
451
|
+
};
|
|
452
|
+
const Message$1 = 3;
|
|
453
|
+
const create$5$1 = async ({
|
|
454
|
+
isMessagePortOpen,
|
|
455
|
+
messagePort
|
|
456
|
+
}) => {
|
|
457
|
+
if (!isMessagePort(messagePort)) {
|
|
458
|
+
throw new IpcError('port must be of type MessagePort');
|
|
459
|
+
}
|
|
460
|
+
if (isMessagePortOpen) {
|
|
461
|
+
return messagePort;
|
|
462
|
+
}
|
|
463
|
+
const eventPromise = getFirstEvent(messagePort, {
|
|
464
|
+
message: Message$1
|
|
465
|
+
});
|
|
466
|
+
messagePort.start();
|
|
467
|
+
const {
|
|
468
|
+
event,
|
|
469
|
+
type
|
|
470
|
+
} = await eventPromise;
|
|
471
|
+
if (type !== Message$1) {
|
|
472
|
+
throw new IpcError('Failed to wait for ipc message');
|
|
473
|
+
}
|
|
474
|
+
if (event.data !== readyMessage) {
|
|
475
|
+
throw new IpcError('unexpected first message');
|
|
476
|
+
}
|
|
477
|
+
return messagePort;
|
|
478
|
+
};
|
|
479
|
+
const signal$1 = messagePort => {
|
|
480
|
+
messagePort.start();
|
|
481
|
+
};
|
|
482
|
+
class IpcParentWithMessagePort extends Ipc {
|
|
483
|
+
getData = getData$2;
|
|
484
|
+
send(message) {
|
|
485
|
+
this._rawIpc.postMessage(message);
|
|
486
|
+
}
|
|
487
|
+
sendAndTransfer(message) {
|
|
488
|
+
const transfer = getTransferrables(message);
|
|
489
|
+
this._rawIpc.postMessage(message, transfer);
|
|
490
|
+
}
|
|
491
|
+
dispose() {
|
|
492
|
+
this._rawIpc.close();
|
|
493
|
+
}
|
|
494
|
+
onMessage(callback) {
|
|
495
|
+
this._rawIpc.addEventListener('message', callback);
|
|
496
|
+
}
|
|
497
|
+
onClose(callback) {}
|
|
498
|
+
}
|
|
499
|
+
const wrap$5 = messagePort => {
|
|
500
|
+
return new IpcParentWithMessagePort(messagePort);
|
|
501
|
+
};
|
|
502
|
+
const IpcParentWithMessagePort$1 = {
|
|
503
|
+
__proto__: null,
|
|
504
|
+
create: create$5$1,
|
|
505
|
+
signal: signal$1,
|
|
506
|
+
wrap: wrap$5
|
|
507
|
+
};
|
|
371
508
|
|
|
372
509
|
class CommandNotFoundError extends Error {
|
|
373
510
|
constructor(command) {
|
|
@@ -392,10 +529,10 @@ const execute = (command, ...args) => {
|
|
|
392
529
|
|
|
393
530
|
const Two$1 = '2.0';
|
|
394
531
|
const callbacks = Object.create(null);
|
|
395
|
-
const get$
|
|
532
|
+
const get$2 = id => {
|
|
396
533
|
return callbacks[id];
|
|
397
534
|
};
|
|
398
|
-
const remove = id => {
|
|
535
|
+
const remove$1 = id => {
|
|
399
536
|
delete callbacks[id];
|
|
400
537
|
};
|
|
401
538
|
class JsonRpcError extends Error {
|
|
@@ -541,14 +678,14 @@ const warn = (...args) => {
|
|
|
541
678
|
console.warn(...args);
|
|
542
679
|
};
|
|
543
680
|
const resolve = (id, response) => {
|
|
544
|
-
const fn = get$
|
|
681
|
+
const fn = get$2(id);
|
|
545
682
|
if (!fn) {
|
|
546
683
|
console.log(response);
|
|
547
684
|
warn(`callback ${id} may already be disposed`);
|
|
548
685
|
return;
|
|
549
686
|
}
|
|
550
687
|
fn(response);
|
|
551
|
-
remove(id);
|
|
688
|
+
remove$1(id);
|
|
552
689
|
};
|
|
553
690
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
554
691
|
const getErrorType = prettyError => {
|
|
@@ -604,7 +741,7 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
|
|
|
604
741
|
const errorProperty = getErrorProperty(error, prettyError);
|
|
605
742
|
return create$1$1(id, errorProperty);
|
|
606
743
|
};
|
|
607
|
-
const create$
|
|
744
|
+
const create$a = (message, result) => {
|
|
608
745
|
return {
|
|
609
746
|
id: message.id,
|
|
610
747
|
jsonrpc: Two$1,
|
|
@@ -613,7 +750,7 @@ const create$6 = (message, result) => {
|
|
|
613
750
|
};
|
|
614
751
|
const getSuccessResponse = (message, result) => {
|
|
615
752
|
const resultProperty = result ?? null;
|
|
616
|
-
return create$
|
|
753
|
+
return create$a(message, resultProperty);
|
|
617
754
|
};
|
|
618
755
|
const getErrorResponseSimple = (id, error) => {
|
|
619
756
|
return {
|
|
@@ -707,7 +844,7 @@ const handleJsonRpcMessage = async (...args) => {
|
|
|
707
844
|
|
|
708
845
|
const Two = '2.0';
|
|
709
846
|
|
|
710
|
-
const create$
|
|
847
|
+
const create$9 = (method, params) => {
|
|
711
848
|
return {
|
|
712
849
|
jsonrpc: Two,
|
|
713
850
|
method,
|
|
@@ -715,7 +852,7 @@ const create$5 = (method, params) => {
|
|
|
715
852
|
};
|
|
716
853
|
};
|
|
717
854
|
|
|
718
|
-
const create$
|
|
855
|
+
const create$8 = (id, method, params) => {
|
|
719
856
|
const message = {
|
|
720
857
|
id,
|
|
721
858
|
jsonrpc: Two,
|
|
@@ -726,12 +863,12 @@ const create$4 = (id, method, params) => {
|
|
|
726
863
|
};
|
|
727
864
|
|
|
728
865
|
let id = 0;
|
|
729
|
-
const create$
|
|
866
|
+
const create$7 = () => {
|
|
730
867
|
return ++id;
|
|
731
868
|
};
|
|
732
869
|
|
|
733
870
|
const registerPromise = map => {
|
|
734
|
-
const id = create$
|
|
871
|
+
const id = create$7();
|
|
735
872
|
const {
|
|
736
873
|
promise,
|
|
737
874
|
resolve
|
|
@@ -748,7 +885,7 @@ const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer)
|
|
|
748
885
|
id,
|
|
749
886
|
promise
|
|
750
887
|
} = registerPromise(callbacks);
|
|
751
|
-
const message = create$
|
|
888
|
+
const message = create$8(id, method, params);
|
|
752
889
|
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
753
890
|
ipc.sendAndTransfer(message);
|
|
754
891
|
} else {
|
|
@@ -784,7 +921,7 @@ const createRpc = ipc => {
|
|
|
784
921
|
* @deprecated
|
|
785
922
|
*/
|
|
786
923
|
send(method, ...params) {
|
|
787
|
-
const message = create$
|
|
924
|
+
const message = create$9(method, params);
|
|
788
925
|
ipc.send(message);
|
|
789
926
|
}
|
|
790
927
|
};
|
|
@@ -824,7 +961,84 @@ const listen$1 = async (module, options) => {
|
|
|
824
961
|
return ipc;
|
|
825
962
|
};
|
|
826
963
|
|
|
827
|
-
const create$
|
|
964
|
+
const create$6 = async ({
|
|
965
|
+
commandMap,
|
|
966
|
+
isMessagePortOpen = true,
|
|
967
|
+
messagePort
|
|
968
|
+
}) => {
|
|
969
|
+
// TODO create a commandMap per rpc instance
|
|
970
|
+
register(commandMap);
|
|
971
|
+
const rawIpc = await IpcParentWithMessagePort$1.create({
|
|
972
|
+
isMessagePortOpen,
|
|
973
|
+
messagePort
|
|
974
|
+
});
|
|
975
|
+
const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
|
|
976
|
+
handleIpc(ipc);
|
|
977
|
+
const rpc = createRpc(ipc);
|
|
978
|
+
messagePort.start();
|
|
979
|
+
return rpc;
|
|
980
|
+
};
|
|
981
|
+
|
|
982
|
+
const create$5 = async ({
|
|
983
|
+
commandMap,
|
|
984
|
+
isMessagePortOpen,
|
|
985
|
+
send
|
|
986
|
+
}) => {
|
|
987
|
+
const {
|
|
988
|
+
port1,
|
|
989
|
+
port2
|
|
990
|
+
} = new MessageChannel();
|
|
991
|
+
await send(port1);
|
|
992
|
+
return create$6({
|
|
993
|
+
commandMap,
|
|
994
|
+
isMessagePortOpen,
|
|
995
|
+
messagePort: port2
|
|
996
|
+
});
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
const createSharedLazyRpc = factory => {
|
|
1000
|
+
let rpcPromise;
|
|
1001
|
+
const getOrCreate = () => {
|
|
1002
|
+
if (!rpcPromise) {
|
|
1003
|
+
rpcPromise = factory();
|
|
1004
|
+
}
|
|
1005
|
+
return rpcPromise;
|
|
1006
|
+
};
|
|
1007
|
+
return {
|
|
1008
|
+
async dispose() {
|
|
1009
|
+
const rpc = await getOrCreate();
|
|
1010
|
+
await rpc.dispose();
|
|
1011
|
+
},
|
|
1012
|
+
async invoke(method, ...params) {
|
|
1013
|
+
const rpc = await getOrCreate();
|
|
1014
|
+
return rpc.invoke(method, ...params);
|
|
1015
|
+
},
|
|
1016
|
+
async invokeAndTransfer(method, ...params) {
|
|
1017
|
+
const rpc = await getOrCreate();
|
|
1018
|
+
return rpc.invokeAndTransfer(method, ...params);
|
|
1019
|
+
},
|
|
1020
|
+
async send(method, ...params) {
|
|
1021
|
+
const rpc = await getOrCreate();
|
|
1022
|
+
rpc.send(method, ...params);
|
|
1023
|
+
}
|
|
1024
|
+
};
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
const create$4 = async ({
|
|
1028
|
+
commandMap,
|
|
1029
|
+
isMessagePortOpen,
|
|
1030
|
+
send
|
|
1031
|
+
}) => {
|
|
1032
|
+
return createSharedLazyRpc(() => {
|
|
1033
|
+
return create$5({
|
|
1034
|
+
commandMap,
|
|
1035
|
+
isMessagePortOpen,
|
|
1036
|
+
send
|
|
1037
|
+
});
|
|
1038
|
+
});
|
|
1039
|
+
};
|
|
1040
|
+
|
|
1041
|
+
const create$3 = async ({
|
|
828
1042
|
commandMap
|
|
829
1043
|
}) => {
|
|
830
1044
|
// TODO create a commandMap per rpc instance
|
|
@@ -835,6 +1049,123 @@ const create$2 = async ({
|
|
|
835
1049
|
return rpc;
|
|
836
1050
|
};
|
|
837
1051
|
|
|
1052
|
+
const createMockRpc = ({
|
|
1053
|
+
commandMap
|
|
1054
|
+
}) => {
|
|
1055
|
+
const invocations = [];
|
|
1056
|
+
const invoke = (method, ...params) => {
|
|
1057
|
+
invocations.push([method, ...params]);
|
|
1058
|
+
const command = commandMap[method];
|
|
1059
|
+
if (!command) {
|
|
1060
|
+
throw new Error(`command ${method} not found`);
|
|
1061
|
+
}
|
|
1062
|
+
return command(...params);
|
|
1063
|
+
};
|
|
1064
|
+
const mockRpc = {
|
|
1065
|
+
invocations,
|
|
1066
|
+
invoke,
|
|
1067
|
+
invokeAndTransfer: invoke
|
|
1068
|
+
};
|
|
1069
|
+
return mockRpc;
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
const rpcs = Object.create(null);
|
|
1073
|
+
const set$3 = (id, rpc) => {
|
|
1074
|
+
rpcs[id] = rpc;
|
|
1075
|
+
};
|
|
1076
|
+
const get$1 = id => {
|
|
1077
|
+
return rpcs[id];
|
|
1078
|
+
};
|
|
1079
|
+
const remove = id => {
|
|
1080
|
+
delete rpcs[id];
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
1084
|
+
const create$2 = rpcId => {
|
|
1085
|
+
return {
|
|
1086
|
+
async dispose() {
|
|
1087
|
+
const rpc = get$1(rpcId);
|
|
1088
|
+
await rpc.dispose();
|
|
1089
|
+
},
|
|
1090
|
+
// @ts-ignore
|
|
1091
|
+
invoke(method, ...params) {
|
|
1092
|
+
const rpc = get$1(rpcId);
|
|
1093
|
+
// @ts-ignore
|
|
1094
|
+
return rpc.invoke(method, ...params);
|
|
1095
|
+
},
|
|
1096
|
+
// @ts-ignore
|
|
1097
|
+
invokeAndTransfer(method, ...params) {
|
|
1098
|
+
const rpc = get$1(rpcId);
|
|
1099
|
+
// @ts-ignore
|
|
1100
|
+
return rpc.invokeAndTransfer(method, ...params);
|
|
1101
|
+
},
|
|
1102
|
+
registerMockRpc(commandMap) {
|
|
1103
|
+
const mockRpc = createMockRpc({
|
|
1104
|
+
commandMap
|
|
1105
|
+
});
|
|
1106
|
+
set$3(rpcId, mockRpc);
|
|
1107
|
+
// @ts-ignore
|
|
1108
|
+
mockRpc[Symbol.dispose] = () => {
|
|
1109
|
+
remove(rpcId);
|
|
1110
|
+
};
|
|
1111
|
+
// @ts-ignore
|
|
1112
|
+
return mockRpc;
|
|
1113
|
+
},
|
|
1114
|
+
set(rpc) {
|
|
1115
|
+
set$3(rpcId, rpc);
|
|
1116
|
+
}
|
|
1117
|
+
};
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
const Button$1 = 1;
|
|
1121
|
+
const Div = 4;
|
|
1122
|
+
const Input = 6;
|
|
1123
|
+
const Span = 8;
|
|
1124
|
+
const Table = 9;
|
|
1125
|
+
const TBody = 10;
|
|
1126
|
+
const Td = 11;
|
|
1127
|
+
const Text = 12;
|
|
1128
|
+
const Th = 13;
|
|
1129
|
+
const THead = 14;
|
|
1130
|
+
const Tr = 15;
|
|
1131
|
+
const Search = 42;
|
|
1132
|
+
const Label = 66;
|
|
1133
|
+
const Reference = 100;
|
|
1134
|
+
|
|
1135
|
+
const Button = 'event.button';
|
|
1136
|
+
const ClientX = 'event.clientX';
|
|
1137
|
+
const ClientY = 'event.clientY';
|
|
1138
|
+
const TargetName = 'event.target.name';
|
|
1139
|
+
const TargetValue = 'event.target.value';
|
|
1140
|
+
|
|
1141
|
+
const ChatStorageWorker = 6003;
|
|
1142
|
+
const RendererWorker = 1;
|
|
1143
|
+
|
|
1144
|
+
const SetCss = 'Viewlet.setCss';
|
|
1145
|
+
const SetDom2 = 'Viewlet.setDom2';
|
|
1146
|
+
const SetPatches = 'Viewlet.setPatches';
|
|
1147
|
+
|
|
1148
|
+
const {
|
|
1149
|
+
invoke: invoke$1,
|
|
1150
|
+
set: set$2
|
|
1151
|
+
} = create$2(ChatStorageWorker);
|
|
1152
|
+
|
|
1153
|
+
const {
|
|
1154
|
+
invoke,
|
|
1155
|
+
invokeAndTransfer,
|
|
1156
|
+
set: set$1
|
|
1157
|
+
} = create$2(RendererWorker);
|
|
1158
|
+
const showContextMenu2 = async (uid, menuId, x, y, args) => {
|
|
1159
|
+
number(uid);
|
|
1160
|
+
number(menuId);
|
|
1161
|
+
number(x);
|
|
1162
|
+
number(y);
|
|
1163
|
+
await invoke('ContextMenu.show2', uid, menuId, x, y, args);
|
|
1164
|
+
};
|
|
1165
|
+
const sendMessagePortToChatStorageWorker$1 = async port => {
|
|
1166
|
+
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatStorageWorker', port, 'HandleMessagePort.handleMessagePort');
|
|
1167
|
+
};
|
|
1168
|
+
|
|
838
1169
|
const toCommandId = key => {
|
|
839
1170
|
const dotIndex = key.indexOf('.');
|
|
840
1171
|
return key.slice(dotIndex + 1);
|
|
@@ -1079,7 +1410,6 @@ const createDefaultState = () => {
|
|
|
1079
1410
|
eventStoreName: 'chat-view-events',
|
|
1080
1411
|
filterValue: '',
|
|
1081
1412
|
height: 0,
|
|
1082
|
-
indexedDbSupportOverride: undefined,
|
|
1083
1413
|
initial: false,
|
|
1084
1414
|
platform: 0,
|
|
1085
1415
|
selectedDetailTab: Response,
|
|
@@ -1171,30 +1501,31 @@ const diff2 = uid => {
|
|
|
1171
1501
|
return diff(oldState, newState);
|
|
1172
1502
|
};
|
|
1173
1503
|
|
|
1174
|
-
const
|
|
1175
|
-
return
|
|
1176
|
-
...state,
|
|
1177
|
-
selectedEvent: null,
|
|
1178
|
-
selectedEventId: null,
|
|
1179
|
-
selectedEventIndex: null
|
|
1180
|
-
};
|
|
1504
|
+
const getMenuIds = () => {
|
|
1505
|
+
return [555, 556, 557];
|
|
1181
1506
|
};
|
|
1182
1507
|
|
|
1183
|
-
const
|
|
1184
|
-
|
|
1508
|
+
const getErrorMessage = error => {
|
|
1509
|
+
if (error instanceof Error) {
|
|
1510
|
+
return error.message;
|
|
1511
|
+
}
|
|
1512
|
+
if (typeof error === 'string') {
|
|
1513
|
+
return error;
|
|
1514
|
+
}
|
|
1515
|
+
if (error && typeof error === 'object' && 'message' in error && typeof error.message === 'string') {
|
|
1516
|
+
return error.message;
|
|
1517
|
+
}
|
|
1518
|
+
return undefined;
|
|
1185
1519
|
};
|
|
1186
|
-
|
|
1187
|
-
const
|
|
1188
|
-
if (
|
|
1189
|
-
return
|
|
1520
|
+
const getFailedToLoadMessage = (sessionId, error) => {
|
|
1521
|
+
const errorMessage = getErrorMessage(error);
|
|
1522
|
+
if (errorMessage) {
|
|
1523
|
+
return `Failed to load chat debug session "${sessionId}": ${errorMessage}`;
|
|
1190
1524
|
}
|
|
1191
|
-
return {
|
|
1192
|
-
...state,
|
|
1193
|
-
selectedDetailTab: value
|
|
1194
|
-
};
|
|
1525
|
+
return `Failed to load chat debug session "${sessionId}". Please try again.`;
|
|
1195
1526
|
};
|
|
1196
1527
|
|
|
1197
|
-
const hasMatchingToolName
|
|
1528
|
+
const hasMatchingToolName = (startedEvent, finishedEvent) => {
|
|
1198
1529
|
if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
|
|
1199
1530
|
return startedEvent.toolName === finishedEvent.toolName;
|
|
1200
1531
|
}
|
|
@@ -1202,27 +1533,27 @@ const hasMatchingToolName$1 = (startedEvent, finishedEvent) => {
|
|
|
1202
1533
|
};
|
|
1203
1534
|
|
|
1204
1535
|
const isMatchingToolExecutionPair = (startedEvent, finishedEvent) => {
|
|
1205
|
-
return startedEvent.sessionId === finishedEvent.sessionId && hasMatchingToolName
|
|
1536
|
+
return startedEvent.sessionId === finishedEvent.sessionId && hasMatchingToolName(startedEvent, finishedEvent);
|
|
1206
1537
|
};
|
|
1207
1538
|
|
|
1208
|
-
const startedEventType
|
|
1209
|
-
const finishedEventType
|
|
1539
|
+
const startedEventType = 'tool-execution-started';
|
|
1540
|
+
const finishedEventType = 'tool-execution-finished';
|
|
1210
1541
|
const mergedEventType = 'tool-execution';
|
|
1211
1542
|
|
|
1212
1543
|
const isToolExecutionFinishedEvent = event => {
|
|
1213
|
-
return event.type === finishedEventType
|
|
1544
|
+
return event.type === finishedEventType;
|
|
1214
1545
|
};
|
|
1215
1546
|
|
|
1216
1547
|
const isToolExecutionStartedEvent = event => {
|
|
1217
|
-
return event.type === startedEventType
|
|
1548
|
+
return event.type === startedEventType;
|
|
1218
1549
|
};
|
|
1219
1550
|
|
|
1220
|
-
const getTimestamp
|
|
1551
|
+
const getTimestamp = value => {
|
|
1221
1552
|
return typeof value === 'string' || typeof value === 'number' ? value : undefined;
|
|
1222
1553
|
};
|
|
1223
1554
|
|
|
1224
1555
|
const getEndedTimestamp = event => {
|
|
1225
|
-
return getTimestamp
|
|
1556
|
+
return getTimestamp(event.ended) ?? getTimestamp(event.endTime) ?? getTimestamp(event.endTimestamp) ?? getTimestamp(event.timestamp);
|
|
1226
1557
|
};
|
|
1227
1558
|
|
|
1228
1559
|
const eventStableIds = new WeakMap();
|
|
@@ -1241,14 +1572,14 @@ const getOrCreateStableEventId = event => {
|
|
|
1241
1572
|
};
|
|
1242
1573
|
|
|
1243
1574
|
const getStartedTimestamp = event => {
|
|
1244
|
-
return getTimestamp
|
|
1575
|
+
return getTimestamp(event.started) ?? getTimestamp(event.startTime) ?? getTimestamp(event.startTimestamp) ?? getTimestamp(event.timestamp);
|
|
1245
1576
|
};
|
|
1246
1577
|
|
|
1247
1578
|
const setStableEventId = (event, stableEventId) => {
|
|
1248
1579
|
eventStableIds.set(event, stableEventId);
|
|
1249
1580
|
};
|
|
1250
1581
|
|
|
1251
|
-
const mergeToolExecutionEvents
|
|
1582
|
+
const mergeToolExecutionEvents = (startedEvent, finishedEvent) => {
|
|
1252
1583
|
const ended = getEndedTimestamp(finishedEvent);
|
|
1253
1584
|
const {
|
|
1254
1585
|
eventId
|
|
@@ -1284,7 +1615,7 @@ const collapseToolExecutionEvents = events => {
|
|
|
1284
1615
|
if (isToolExecutionStartedEvent(event)) {
|
|
1285
1616
|
const nextEvent = events[i + 1];
|
|
1286
1617
|
if (nextEvent && isToolExecutionFinishedEvent(nextEvent) && isMatchingToolExecutionPair(event, nextEvent)) {
|
|
1287
|
-
collapsedEvents.push(mergeToolExecutionEvents
|
|
1618
|
+
collapsedEvents.push(mergeToolExecutionEvents(event, nextEvent));
|
|
1288
1619
|
i++;
|
|
1289
1620
|
continue;
|
|
1290
1621
|
}
|
|
@@ -1361,6 +1692,24 @@ const getFilteredEvents = (events, filterValue, eventCategoryFilter, showInputEv
|
|
|
1361
1692
|
return filteredByCategory.filter(event => JSON.stringify(event).toLowerCase().includes(filterText));
|
|
1362
1693
|
};
|
|
1363
1694
|
|
|
1695
|
+
const ParseChatDebugUriErrorCode = {
|
|
1696
|
+
InvalidSessionId: 'invalid-session-id',
|
|
1697
|
+
InvalidUriEncoding: 'invalid-uri-encoding',
|
|
1698
|
+
InvalidUriFormat: 'invalid-uri-format',
|
|
1699
|
+
MissingUri: 'missing-uri'
|
|
1700
|
+
};
|
|
1701
|
+
|
|
1702
|
+
const getInvalidUriMessage = (uri, code) => {
|
|
1703
|
+
if (code === ParseChatDebugUriErrorCode.MissingUri) {
|
|
1704
|
+
return 'Unable to load debug session: missing URI. Expected format: chat-debug://<sessionId>.';
|
|
1705
|
+
}
|
|
1706
|
+
return `Unable to load debug session: invalid URI "${uri}". Expected format: chat-debug://<sessionId>.`;
|
|
1707
|
+
};
|
|
1708
|
+
|
|
1709
|
+
const getSessionNotFoundMessage = sessionId => {
|
|
1710
|
+
return `No chat session found for sessionId "${sessionId}".`;
|
|
1711
|
+
};
|
|
1712
|
+
|
|
1364
1713
|
const toTimeNumber = value => {
|
|
1365
1714
|
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
1366
1715
|
return value;
|
|
@@ -1512,558 +1861,409 @@ const getTimelineInfo = (events, startValue, endValue) => {
|
|
|
1512
1861
|
};
|
|
1513
1862
|
};
|
|
1514
1863
|
|
|
1515
|
-
const
|
|
1516
|
-
|
|
1517
|
-
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
1864
|
+
const listChatViewEvents$1 = async sessionId => {
|
|
1865
|
+
return invoke$1('ChatStorage.listChatViewEvents', sessionId);
|
|
1518
1866
|
};
|
|
1519
|
-
const
|
|
1520
|
-
|
|
1521
|
-
return events.findIndex(candidate => getStableEventId(candidate) === stableEventId);
|
|
1867
|
+
const loadSelectedEvent$1 = async (sessionId, eventId, type) => {
|
|
1868
|
+
return invoke$1('ChatStorage.loadSelectedEvent', sessionId, eventId, type);
|
|
1522
1869
|
};
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
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;
|
|
1870
|
+
|
|
1871
|
+
const listChatViewEventsDependencies = {
|
|
1872
|
+
listChatViewEventsFromWorker: listChatViewEvents$1
|
|
1540
1873
|
};
|
|
1541
|
-
const
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
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;
|
|
1874
|
+
const listChatViewEvents = async (sessionId, _databaseName, _dataBaseVersion, _eventStoreName, _sessionIdIndexName) => {
|
|
1875
|
+
try {
|
|
1876
|
+
return await listChatViewEventsDependencies.listChatViewEventsFromWorker(sessionId);
|
|
1877
|
+
} catch (error) {
|
|
1878
|
+
return {
|
|
1879
|
+
error,
|
|
1880
|
+
type: 'error'
|
|
1881
|
+
};
|
|
1557
1882
|
}
|
|
1558
|
-
return newIndex;
|
|
1559
1883
|
};
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
selectedEventIndex
|
|
1567
|
-
};
|
|
1884
|
+
|
|
1885
|
+
const loadSelectedEventDependencies = {
|
|
1886
|
+
loadSelectedEventFromWorker: loadSelectedEvent$1
|
|
1887
|
+
};
|
|
1888
|
+
const loadSelectedEvent = async (_databaseName, _dataBaseVersion, _eventStoreName, sessionId, _sessionIdIndexName, eventId, type) => {
|
|
1889
|
+
return loadSelectedEventDependencies.loadSelectedEventFromWorker(sessionId, eventId, type);
|
|
1568
1890
|
};
|
|
1569
1891
|
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
};
|
|
1575
|
-
return withPreservedSelection$1(state, nextState);
|
|
1576
|
-
};
|
|
1577
|
-
|
|
1578
|
-
let workerRpc;
|
|
1579
|
-
const setWorkerRpc = value => {
|
|
1580
|
-
workerRpc = value;
|
|
1581
|
-
};
|
|
1582
|
-
const invoke = async (method, ...params) => {
|
|
1583
|
-
if (!workerRpc) {
|
|
1584
|
-
throw new Error('worker rpc is not initialized');
|
|
1585
|
-
}
|
|
1586
|
-
return workerRpc.invoke(method, ...params);
|
|
1587
|
-
};
|
|
1588
|
-
|
|
1589
|
-
const chatStorageWorkerClientDependencies = {
|
|
1590
|
-
invoke: invoke
|
|
1591
|
-
};
|
|
1592
|
-
const listChatViewEvents$1 = async sessionId => {
|
|
1593
|
-
return chatStorageWorkerClientDependencies.invoke('ChatStorage.listChatViewEvents', sessionId);
|
|
1594
|
-
};
|
|
1595
|
-
const loadSelectedEvent$1 = async (sessionId, eventId, type) => {
|
|
1596
|
-
return chatStorageWorkerClientDependencies.invoke('ChatStorage.loadSelectedEvent', sessionId, eventId, type);
|
|
1597
|
-
};
|
|
1598
|
-
|
|
1599
|
-
// cspell:ignore IDBP
|
|
1600
|
-
|
|
1601
|
-
const startedEventType = 'tool-execution-started';
|
|
1602
|
-
const finishedEventType = 'tool-execution-finished';
|
|
1603
|
-
const getRawEventBySessionIdAndEventId = async (store, sessionId, sessionIdIndexName, eventId) => {
|
|
1604
|
-
if (eventId < 1) {
|
|
1605
|
-
return undefined;
|
|
1606
|
-
}
|
|
1607
|
-
if (store.indexNames.contains(sessionIdIndexName)) {
|
|
1608
|
-
const index = store.index(sessionIdIndexName);
|
|
1609
|
-
const keys = await index.getAllKeys(sessionId, eventId);
|
|
1610
|
-
if (keys.length < eventId) {
|
|
1611
|
-
return undefined;
|
|
1612
|
-
}
|
|
1613
|
-
const key = keys.at(-1);
|
|
1614
|
-
if (key === undefined) {
|
|
1615
|
-
return undefined;
|
|
1616
|
-
}
|
|
1617
|
-
const event = await store.get(key);
|
|
1618
|
-
return event;
|
|
1619
|
-
}
|
|
1620
|
-
const all = await store.getAll();
|
|
1621
|
-
const events = all.filter(event => event.sessionId === sessionId);
|
|
1622
|
-
return events[eventId - 1];
|
|
1623
|
-
};
|
|
1624
|
-
const getTimestamp = value => {
|
|
1625
|
-
return typeof value === 'string' || typeof value === 'number' ? value : undefined;
|
|
1626
|
-
};
|
|
1627
|
-
const hasMatchingToolName = (startedEvent, finishedEvent) => {
|
|
1628
|
-
if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
|
|
1629
|
-
return startedEvent.toolName === finishedEvent.toolName;
|
|
1630
|
-
}
|
|
1631
|
-
return true;
|
|
1632
|
-
};
|
|
1633
|
-
const mergeToolExecutionEvents = (startedEvent, finishedEvent, eventId) => {
|
|
1634
|
-
const ended = getTimestamp(finishedEvent.ended) ?? getTimestamp(finishedEvent.endTime) ?? getTimestamp(finishedEvent.timestamp);
|
|
1635
|
-
const started = getTimestamp(startedEvent.started) ?? getTimestamp(startedEvent.startTime) ?? getTimestamp(startedEvent.timestamp);
|
|
1636
|
-
return {
|
|
1637
|
-
...startedEvent,
|
|
1638
|
-
...finishedEvent,
|
|
1639
|
-
...(ended === undefined ? {} : {
|
|
1640
|
-
ended
|
|
1641
|
-
}),
|
|
1642
|
-
eventId,
|
|
1643
|
-
...(started === undefined ? {} : {
|
|
1644
|
-
started
|
|
1645
|
-
}),
|
|
1646
|
-
type: 'tool-execution'
|
|
1647
|
-
};
|
|
1648
|
-
};
|
|
1649
|
-
const getEventDetailsBySessionIdAndEventId = async (store, sessionId, sessionIdIndexName, eventId, summaryType) => {
|
|
1650
|
-
const event = await getRawEventBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId);
|
|
1651
|
-
if (!event) {
|
|
1652
|
-
return undefined;
|
|
1653
|
-
}
|
|
1654
|
-
if (summaryType !== 'tool-execution') {
|
|
1892
|
+
const chatDebugUriPattern = /^chat-debug:\/\/([^/?#]+)$/;
|
|
1893
|
+
const invalidSessionIdPattern = /[/?#]/;
|
|
1894
|
+
const parseChatDebugUri = uri => {
|
|
1895
|
+
if (!uri) {
|
|
1655
1896
|
return {
|
|
1656
|
-
|
|
1657
|
-
|
|
1897
|
+
code: ParseChatDebugUriErrorCode.MissingUri,
|
|
1898
|
+
message: 'Missing URI',
|
|
1899
|
+
type: 'error'
|
|
1658
1900
|
};
|
|
1659
1901
|
}
|
|
1660
|
-
|
|
1902
|
+
const match = uri.match(chatDebugUriPattern);
|
|
1903
|
+
if (!match) {
|
|
1661
1904
|
return {
|
|
1662
|
-
|
|
1663
|
-
|
|
1905
|
+
code: ParseChatDebugUriErrorCode.InvalidUriFormat,
|
|
1906
|
+
message: 'Invalid URI format',
|
|
1907
|
+
type: 'error'
|
|
1664
1908
|
};
|
|
1665
1909
|
}
|
|
1666
|
-
const
|
|
1667
|
-
|
|
1910
|
+
const encodedSessionId = match[1];
|
|
1911
|
+
let sessionId;
|
|
1912
|
+
try {
|
|
1913
|
+
sessionId = decodeURIComponent(encodedSessionId);
|
|
1914
|
+
} catch {
|
|
1668
1915
|
return {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
}
|
|
1673
|
-
return mergeToolExecutionEvents(event, nextEvent, eventId);
|
|
1674
|
-
};
|
|
1675
|
-
|
|
1676
|
-
const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
|
|
1677
|
-
let idbProxyableTypes;
|
|
1678
|
-
let cursorAdvanceMethods;
|
|
1679
|
-
// This is a function to prevent it throwing up in node environments.
|
|
1680
|
-
function getIdbProxyableTypes() {
|
|
1681
|
-
return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
|
|
1682
|
-
}
|
|
1683
|
-
// This is a function to prevent it throwing up in node environments.
|
|
1684
|
-
function getCursorAdvanceMethods() {
|
|
1685
|
-
return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
|
|
1686
|
-
}
|
|
1687
|
-
const transactionDoneMap = new WeakMap();
|
|
1688
|
-
const transformCache = new WeakMap();
|
|
1689
|
-
const reverseTransformCache = new WeakMap();
|
|
1690
|
-
function promisifyRequest(request) {
|
|
1691
|
-
const promise = new Promise((resolve, reject) => {
|
|
1692
|
-
const unlisten = () => {
|
|
1693
|
-
request.removeEventListener('success', success);
|
|
1694
|
-
request.removeEventListener('error', error);
|
|
1695
|
-
};
|
|
1696
|
-
const success = () => {
|
|
1697
|
-
resolve(wrap(request.result));
|
|
1698
|
-
unlisten();
|
|
1699
|
-
};
|
|
1700
|
-
const error = () => {
|
|
1701
|
-
reject(request.error);
|
|
1702
|
-
unlisten();
|
|
1703
|
-
};
|
|
1704
|
-
request.addEventListener('success', success);
|
|
1705
|
-
request.addEventListener('error', error);
|
|
1706
|
-
});
|
|
1707
|
-
// This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
|
|
1708
|
-
// is because we create many promises from a single IDBRequest.
|
|
1709
|
-
reverseTransformCache.set(promise, request);
|
|
1710
|
-
return promise;
|
|
1711
|
-
}
|
|
1712
|
-
function cacheDonePromiseForTransaction(tx) {
|
|
1713
|
-
// Early bail if we've already created a done promise for this transaction.
|
|
1714
|
-
if (transactionDoneMap.has(tx)) return;
|
|
1715
|
-
const done = new Promise((resolve, reject) => {
|
|
1716
|
-
const unlisten = () => {
|
|
1717
|
-
tx.removeEventListener('complete', complete);
|
|
1718
|
-
tx.removeEventListener('error', error);
|
|
1719
|
-
tx.removeEventListener('abort', error);
|
|
1720
|
-
};
|
|
1721
|
-
const complete = () => {
|
|
1722
|
-
resolve();
|
|
1723
|
-
unlisten();
|
|
1724
|
-
};
|
|
1725
|
-
const error = () => {
|
|
1726
|
-
reject(tx.error || new DOMException('AbortError', 'AbortError'));
|
|
1727
|
-
unlisten();
|
|
1916
|
+
code: ParseChatDebugUriErrorCode.InvalidUriEncoding,
|
|
1917
|
+
message: 'Invalid URI encoding',
|
|
1918
|
+
type: 'error'
|
|
1728
1919
|
};
|
|
1729
|
-
tx.addEventListener('complete', complete);
|
|
1730
|
-
tx.addEventListener('error', error);
|
|
1731
|
-
tx.addEventListener('abort', error);
|
|
1732
|
-
});
|
|
1733
|
-
// Cache it for later retrieval.
|
|
1734
|
-
transactionDoneMap.set(tx, done);
|
|
1735
|
-
}
|
|
1736
|
-
let idbProxyTraps = {
|
|
1737
|
-
get(target, prop, receiver) {
|
|
1738
|
-
if (target instanceof IDBTransaction) {
|
|
1739
|
-
// Special handling for transaction.done.
|
|
1740
|
-
if (prop === 'done') return transactionDoneMap.get(target);
|
|
1741
|
-
// Make tx.store return the only store in the transaction, or undefined if there are many.
|
|
1742
|
-
if (prop === 'store') {
|
|
1743
|
-
return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
// Else transform whatever we get back.
|
|
1747
|
-
return wrap(target[prop]);
|
|
1748
|
-
},
|
|
1749
|
-
set(target, prop, value) {
|
|
1750
|
-
target[prop] = value;
|
|
1751
|
-
return true;
|
|
1752
|
-
},
|
|
1753
|
-
has(target, prop) {
|
|
1754
|
-
if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
|
|
1755
|
-
return true;
|
|
1756
|
-
}
|
|
1757
|
-
return prop in target;
|
|
1758
1920
|
}
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
// Due to expected object equality (which is enforced by the caching in `wrap`), we
|
|
1765
|
-
// only create one new func per func.
|
|
1766
|
-
// Cursor methods are special, as the behaviour is a little more different to standard IDB. In
|
|
1767
|
-
// IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
|
|
1768
|
-
// cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
|
|
1769
|
-
// with real promises, so each advance methods returns a new promise for the cursor object, or
|
|
1770
|
-
// undefined if the end of the cursor has been reached.
|
|
1771
|
-
if (getCursorAdvanceMethods().includes(func)) {
|
|
1772
|
-
return function (...args) {
|
|
1773
|
-
// Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
|
|
1774
|
-
// the original object.
|
|
1775
|
-
func.apply(unwrap(this), args);
|
|
1776
|
-
return wrap(this.request);
|
|
1921
|
+
if (!sessionId || invalidSessionIdPattern.test(sessionId)) {
|
|
1922
|
+
return {
|
|
1923
|
+
code: ParseChatDebugUriErrorCode.InvalidSessionId,
|
|
1924
|
+
message: 'Invalid session id',
|
|
1925
|
+
type: 'error'
|
|
1777
1926
|
};
|
|
1778
1927
|
}
|
|
1779
|
-
return
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
return wrap(func.apply(unwrap(this), args));
|
|
1783
|
-
};
|
|
1784
|
-
}
|
|
1785
|
-
function transformCachableValue(value) {
|
|
1786
|
-
if (typeof value === 'function') return wrapFunction(value);
|
|
1787
|
-
// This doesn't return, it just creates a 'done' promise for the transaction,
|
|
1788
|
-
// which is later returned for transaction.done (see idbObjectHandler).
|
|
1789
|
-
if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
|
|
1790
|
-
if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
|
|
1791
|
-
// Return the same value back if we're not going to transform it.
|
|
1792
|
-
return value;
|
|
1793
|
-
}
|
|
1794
|
-
function wrap(value) {
|
|
1795
|
-
// We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
|
|
1796
|
-
// IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
|
|
1797
|
-
if (value instanceof IDBRequest) return promisifyRequest(value);
|
|
1798
|
-
// If we've already transformed this value before, reuse the transformed value.
|
|
1799
|
-
// This is faster, but it also provides object equality.
|
|
1800
|
-
if (transformCache.has(value)) return transformCache.get(value);
|
|
1801
|
-
const newValue = transformCachableValue(value);
|
|
1802
|
-
// Not all types are transformed.
|
|
1803
|
-
// These may be primitive types, so they can't be WeakMap keys.
|
|
1804
|
-
if (newValue !== value) {
|
|
1805
|
-
transformCache.set(value, newValue);
|
|
1806
|
-
reverseTransformCache.set(newValue, value);
|
|
1807
|
-
}
|
|
1808
|
-
return newValue;
|
|
1809
|
-
}
|
|
1810
|
-
const unwrap = value => reverseTransformCache.get(value);
|
|
1811
|
-
|
|
1812
|
-
/**
|
|
1813
|
-
* Open a database.
|
|
1814
|
-
*
|
|
1815
|
-
* @param name Name of the database.
|
|
1816
|
-
* @param version Schema version.
|
|
1817
|
-
* @param callbacks Additional callbacks.
|
|
1818
|
-
*/
|
|
1819
|
-
function openDB(name, version, {
|
|
1820
|
-
blocked,
|
|
1821
|
-
upgrade,
|
|
1822
|
-
blocking,
|
|
1823
|
-
terminated
|
|
1824
|
-
} = {}) {
|
|
1825
|
-
const request = indexedDB.open(name, version);
|
|
1826
|
-
const openPromise = wrap(request);
|
|
1827
|
-
if (upgrade) {
|
|
1828
|
-
request.addEventListener('upgradeneeded', event => {
|
|
1829
|
-
upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
|
|
1830
|
-
});
|
|
1831
|
-
}
|
|
1832
|
-
if (blocked) {
|
|
1833
|
-
request.addEventListener('blocked', event => blocked(
|
|
1834
|
-
// Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
|
|
1835
|
-
event.oldVersion, event.newVersion, event));
|
|
1836
|
-
}
|
|
1837
|
-
openPromise.then(db => {
|
|
1838
|
-
if (terminated) db.addEventListener('close', () => terminated());
|
|
1839
|
-
if (blocking) {
|
|
1840
|
-
db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
|
|
1841
|
-
}
|
|
1842
|
-
}).catch(() => {});
|
|
1843
|
-
return openPromise;
|
|
1844
|
-
}
|
|
1845
|
-
const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
|
|
1846
|
-
const writeMethods = ['put', 'add', 'delete', 'clear'];
|
|
1847
|
-
const cachedMethods = new Map();
|
|
1848
|
-
function getMethod(target, prop) {
|
|
1849
|
-
if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
|
|
1850
|
-
return;
|
|
1851
|
-
}
|
|
1852
|
-
if (cachedMethods.get(prop)) return cachedMethods.get(prop);
|
|
1853
|
-
const targetFuncName = prop.replace(/FromIndex$/, '');
|
|
1854
|
-
const useIndex = prop !== targetFuncName;
|
|
1855
|
-
const isWrite = writeMethods.includes(targetFuncName);
|
|
1856
|
-
if (
|
|
1857
|
-
// Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
|
|
1858
|
-
!(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
|
|
1859
|
-
return;
|
|
1860
|
-
}
|
|
1861
|
-
const method = async function (storeName, ...args) {
|
|
1862
|
-
// isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
|
|
1863
|
-
const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
|
|
1864
|
-
let target = tx.store;
|
|
1865
|
-
if (useIndex) target = target.index(args.shift());
|
|
1866
|
-
// Must reject if op rejects.
|
|
1867
|
-
// If it's a write operation, must reject if tx.done rejects.
|
|
1868
|
-
// Must reject with op rejection first.
|
|
1869
|
-
// Must resolve with op value.
|
|
1870
|
-
// Must handle both promises (no unhandled rejections)
|
|
1871
|
-
return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
|
|
1928
|
+
return {
|
|
1929
|
+
sessionId,
|
|
1930
|
+
type: 'success'
|
|
1872
1931
|
};
|
|
1873
|
-
cachedMethods.set(prop, method);
|
|
1874
|
-
return method;
|
|
1875
|
-
}
|
|
1876
|
-
replaceTraps(oldTraps => ({
|
|
1877
|
-
...oldTraps,
|
|
1878
|
-
get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
|
|
1879
|
-
has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
|
|
1880
|
-
}));
|
|
1881
|
-
const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
|
|
1882
|
-
const methodMap = {};
|
|
1883
|
-
const advanceResults = new WeakMap();
|
|
1884
|
-
const ittrProxiedCursorToOriginalProxy = new WeakMap();
|
|
1885
|
-
const cursorIteratorTraps = {
|
|
1886
|
-
get(target, prop) {
|
|
1887
|
-
if (!advanceMethodProps.includes(prop)) return target[prop];
|
|
1888
|
-
let cachedFunc = methodMap[prop];
|
|
1889
|
-
if (!cachedFunc) {
|
|
1890
|
-
cachedFunc = methodMap[prop] = function (...args) {
|
|
1891
|
-
advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
|
|
1892
|
-
};
|
|
1893
|
-
}
|
|
1894
|
-
return cachedFunc;
|
|
1895
|
-
}
|
|
1896
|
-
};
|
|
1897
|
-
async function* iterate(...args) {
|
|
1898
|
-
// tslint:disable-next-line:no-this-assignment
|
|
1899
|
-
let cursor = this;
|
|
1900
|
-
if (!(cursor instanceof IDBCursor)) {
|
|
1901
|
-
cursor = await cursor.openCursor(...args);
|
|
1902
|
-
}
|
|
1903
|
-
if (!cursor) return;
|
|
1904
|
-
cursor = cursor;
|
|
1905
|
-
const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
|
|
1906
|
-
ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
|
|
1907
|
-
// Map this double-proxy back to the original, so other cursor methods work.
|
|
1908
|
-
reverseTransformCache.set(proxiedCursor, unwrap(cursor));
|
|
1909
|
-
while (cursor) {
|
|
1910
|
-
yield proxiedCursor;
|
|
1911
|
-
// If one of the advancing methods was not called, call continue().
|
|
1912
|
-
cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
|
|
1913
|
-
advanceResults.delete(proxiedCursor);
|
|
1914
|
-
}
|
|
1915
|
-
}
|
|
1916
|
-
function isIteratorProp(target, prop) {
|
|
1917
|
-
return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
|
|
1918
|
-
}
|
|
1919
|
-
replaceTraps(oldTraps => ({
|
|
1920
|
-
...oldTraps,
|
|
1921
|
-
get(target, prop, receiver) {
|
|
1922
|
-
if (isIteratorProp(target, prop)) return iterate;
|
|
1923
|
-
return oldTraps.get(target, prop, receiver);
|
|
1924
|
-
},
|
|
1925
|
-
has(target, prop) {
|
|
1926
|
-
return isIteratorProp(target, prop) || oldTraps.has(target, prop);
|
|
1927
|
-
}
|
|
1928
|
-
}));
|
|
1929
|
-
|
|
1930
|
-
const openDatabaseDependencies = {
|
|
1931
|
-
openDB: openDB
|
|
1932
|
-
};
|
|
1933
|
-
const openDatabase = async (databaseName, dataBaseVersion) => {
|
|
1934
|
-
return openDatabaseDependencies.openDB(databaseName, dataBaseVersion);
|
|
1935
1932
|
};
|
|
1936
1933
|
|
|
1937
|
-
const
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
openDatabase: openDatabase
|
|
1941
|
-
};
|
|
1942
|
-
const loadSelectedEvent = async (databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, eventId, type) => {
|
|
1943
|
-
const database = await loadSelectedEventDependencies.openDatabase(databaseName, dataBaseVersion);
|
|
1944
|
-
try {
|
|
1945
|
-
if (!database.objectStoreNames.contains(eventStoreName)) {
|
|
1946
|
-
return null;
|
|
1947
|
-
}
|
|
1948
|
-
const transaction = database.transaction(eventStoreName, 'readonly');
|
|
1949
|
-
const store = transaction.objectStore(eventStoreName);
|
|
1950
|
-
const event = await loadSelectedEventDependencies.getEventDetailsBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId, type);
|
|
1951
|
-
return event ?? null;
|
|
1952
|
-
} finally {
|
|
1953
|
-
database.close();
|
|
1954
|
-
}
|
|
1934
|
+
const loadEventsDependencies = {
|
|
1935
|
+
listChatViewEvents: listChatViewEvents,
|
|
1936
|
+
loadSelectedEvent: loadSelectedEvent
|
|
1955
1937
|
};
|
|
1956
|
-
|
|
1957
|
-
const getCurrentEvents$2 = state => {
|
|
1938
|
+
const getCurrentEvents$3 = state => {
|
|
1958
1939
|
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
1959
1940
|
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
1960
1941
|
};
|
|
1961
|
-
const
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1942
|
+
const restoreSelectedEvent = async state => {
|
|
1943
|
+
if (state.selectedEventId === null) {
|
|
1944
|
+
return {
|
|
1945
|
+
...state,
|
|
1946
|
+
selectedEvent: null,
|
|
1947
|
+
selectedEventIndex: null
|
|
1948
|
+
};
|
|
1949
|
+
}
|
|
1950
|
+
const currentEvents = getCurrentEvents$3(state);
|
|
1951
|
+
const selectedEventIndex = currentEvents.findIndex(event => event.eventId === state.selectedEventId);
|
|
1952
|
+
if (selectedEventIndex === -1) {
|
|
1965
1953
|
return {
|
|
1966
1954
|
...state,
|
|
1967
1955
|
selectedEvent: null,
|
|
1968
1956
|
selectedEventId: null,
|
|
1969
|
-
selectedEventIndex
|
|
1957
|
+
selectedEventIndex: null
|
|
1970
1958
|
};
|
|
1971
1959
|
}
|
|
1972
|
-
|
|
1960
|
+
const selectedEvent = currentEvents[selectedEventIndex];
|
|
1961
|
+
if (!selectedEvent || typeof selectedEvent.eventId !== 'number') {
|
|
1973
1962
|
return {
|
|
1974
1963
|
...state,
|
|
1975
|
-
selectedEvent,
|
|
1964
|
+
selectedEvent: null,
|
|
1976
1965
|
selectedEventId: null,
|
|
1977
|
-
selectedEventIndex
|
|
1966
|
+
selectedEventIndex: null
|
|
1978
1967
|
};
|
|
1979
1968
|
}
|
|
1980
|
-
const selectedEventDetails = await
|
|
1969
|
+
const selectedEventDetails = await loadEventsDependencies.loadSelectedEvent(state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionId, state.sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
|
|
1981
1970
|
return {
|
|
1982
1971
|
...state,
|
|
1983
|
-
selectedEvent: selectedEventDetails
|
|
1972
|
+
selectedEvent: selectedEventDetails,
|
|
1984
1973
|
selectedEventId: selectedEvent.eventId,
|
|
1985
1974
|
selectedEventIndex
|
|
1986
1975
|
};
|
|
1987
1976
|
};
|
|
1988
|
-
|
|
1989
|
-
const
|
|
1990
|
-
|
|
1991
|
-
};
|
|
1992
|
-
const isPrimaryButton = button => {
|
|
1993
|
-
return button === 0;
|
|
1994
|
-
};
|
|
1995
|
-
const parseSelectedEventIndex$1 = value => {
|
|
1996
|
-
const parsed = Number.parseInt(value, 10);
|
|
1997
|
-
if (Number.isNaN(parsed) || parsed < 0) {
|
|
1998
|
-
return null;
|
|
1999
|
-
}
|
|
2000
|
-
return parsed;
|
|
2001
|
-
};
|
|
2002
|
-
const handleEventRowClick = async (state, value, button = 0) => {
|
|
2003
|
-
if (!isPrimaryButton(button)) {
|
|
2004
|
-
return state;
|
|
2005
|
-
}
|
|
2006
|
-
const selectedEventIndex = parseSelectedEventIndex$1(value);
|
|
2007
|
-
if (selectedEventIndex === null) {
|
|
1977
|
+
const getStateWithInvalidUri = state => {
|
|
1978
|
+
const parsed = parseChatDebugUri(state.uri);
|
|
1979
|
+
if (parsed.type !== 'error') {
|
|
2008
1980
|
return state;
|
|
2009
1981
|
}
|
|
2010
|
-
return selectEventAtIndex(state, selectedEventIndex, handleEventRowClickDependencies);
|
|
2011
|
-
};
|
|
2012
|
-
|
|
2013
|
-
const handleHeaderContextMenu = state => {
|
|
2014
|
-
return state;
|
|
2015
|
-
};
|
|
2016
|
-
|
|
2017
|
-
const getBoolean = value => {
|
|
2018
|
-
return value === true || value === 'true' || value === 'on' || value === '1';
|
|
2019
|
-
};
|
|
2020
|
-
|
|
2021
|
-
const Filter = 'filter';
|
|
2022
|
-
const EventCategoryFilter = 'eventCategoryFilter';
|
|
2023
|
-
const ShowEventStreamFinishedEvents = 'showEventStreamFinishedEvents';
|
|
2024
|
-
const ShowInputEvents = 'showInputEvents';
|
|
2025
|
-
const ShowResponsePartEvents = 'showResponsePartEvents';
|
|
2026
|
-
const UseDevtoolsLayout = 'useDevtoolsLayout';
|
|
2027
|
-
const SelectedEventIndex = 'selectedEventIndex';
|
|
2028
|
-
const CloseDetails = 'closeDetails';
|
|
2029
|
-
const DetailTab = 'detailTab';
|
|
2030
|
-
const TimelineStartSeconds = 'timelineStartSeconds';
|
|
2031
|
-
const TimelineEndSeconds = 'timelineEndSeconds';
|
|
2032
|
-
const TimelineRangePreset = 'timelineRangePreset';
|
|
2033
|
-
|
|
2034
|
-
const getCurrentEvents$1 = state => {
|
|
2035
|
-
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
2036
|
-
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
2037
|
-
};
|
|
2038
|
-
const parseTimelineRangePreset$1 = value => {
|
|
2039
|
-
if (!value) {
|
|
2040
|
-
return {
|
|
2041
|
-
timelineEndSeconds: '',
|
|
2042
|
-
timelineStartSeconds: ''
|
|
2043
|
-
};
|
|
2044
|
-
}
|
|
2045
|
-
const [timelineStartSeconds = '', timelineEndSeconds = ''] = value.split(':', 2);
|
|
2046
1982
|
return {
|
|
2047
|
-
|
|
2048
|
-
|
|
1983
|
+
...state,
|
|
1984
|
+
errorMessage: getInvalidUriMessage(state.uri, parsed.code),
|
|
1985
|
+
events: [],
|
|
1986
|
+
initial: false,
|
|
1987
|
+
selectedEvent: null,
|
|
1988
|
+
selectedEventId: null,
|
|
1989
|
+
selectedEventIndex: null,
|
|
1990
|
+
sessionId: ''
|
|
2049
1991
|
};
|
|
2050
1992
|
};
|
|
2051
|
-
const
|
|
2052
|
-
const
|
|
2053
|
-
|
|
1993
|
+
const getSessionIdFromUri = state => {
|
|
1994
|
+
const parsed = parseChatDebugUri(state.uri);
|
|
1995
|
+
if (parsed.type === 'error') {
|
|
1996
|
+
return undefined;
|
|
1997
|
+
}
|
|
1998
|
+
return parsed.sessionId;
|
|
2054
1999
|
};
|
|
2055
|
-
const
|
|
2000
|
+
const loadEventsForSessionId = async (state, sessionId) => {
|
|
2056
2001
|
const {
|
|
2057
|
-
|
|
2002
|
+
databaseName,
|
|
2003
|
+
dataBaseVersion,
|
|
2004
|
+
eventStoreName,
|
|
2005
|
+
sessionIdIndexName
|
|
2058
2006
|
} = state;
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2007
|
+
const result = await loadEventsDependencies.listChatViewEvents(sessionId, databaseName, dataBaseVersion, eventStoreName, sessionIdIndexName);
|
|
2008
|
+
if (result.type === 'error') {
|
|
2009
|
+
return {
|
|
2010
|
+
...state,
|
|
2011
|
+
errorMessage: getFailedToLoadMessage(sessionId, result.error),
|
|
2012
|
+
events: [],
|
|
2013
|
+
initial: false,
|
|
2014
|
+
selectedEvent: null,
|
|
2015
|
+
selectedEventId: null,
|
|
2016
|
+
selectedEventIndex: null,
|
|
2017
|
+
sessionId
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
const {
|
|
2021
|
+
events
|
|
2022
|
+
} = result;
|
|
2023
|
+
if (events.length === 0) {
|
|
2024
|
+
return {
|
|
2025
|
+
...state,
|
|
2026
|
+
errorMessage: getSessionNotFoundMessage(sessionId),
|
|
2027
|
+
events: [],
|
|
2028
|
+
initial: false,
|
|
2029
|
+
selectedEvent: null,
|
|
2030
|
+
selectedEventId: null,
|
|
2031
|
+
selectedEventIndex: null,
|
|
2032
|
+
sessionId
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
const nextState = {
|
|
2036
|
+
...state,
|
|
2037
|
+
errorMessage: '',
|
|
2038
|
+
events,
|
|
2039
|
+
initial: false,
|
|
2040
|
+
sessionId
|
|
2041
|
+
};
|
|
2042
|
+
return restoreSelectedEvent(nextState);
|
|
2043
|
+
};
|
|
2044
|
+
const loadEventsFromUri = async state => {
|
|
2045
|
+
const sessionId = getSessionIdFromUri(state);
|
|
2046
|
+
if (!sessionId) {
|
|
2047
|
+
return getStateWithInvalidUri(state);
|
|
2048
|
+
}
|
|
2049
|
+
return loadEventsForSessionId(state, sessionId);
|
|
2050
|
+
};
|
|
2051
|
+
const refreshEvents = async state => {
|
|
2052
|
+
const sessionId = state.sessionId || getSessionIdFromUri(state);
|
|
2053
|
+
if (!sessionId) {
|
|
2054
|
+
return getStateWithInvalidUri(state);
|
|
2055
|
+
}
|
|
2056
|
+
return loadEventsForSessionId(state, sessionId);
|
|
2057
|
+
};
|
|
2058
|
+
|
|
2059
|
+
const refresh = async state => {
|
|
2060
|
+
return refreshEvents(state);
|
|
2061
|
+
};
|
|
2062
|
+
|
|
2063
|
+
const handleClickRefreshDependencies = {
|
|
2064
|
+
refresh: refresh
|
|
2065
|
+
};
|
|
2066
|
+
const handleClickRefresh = async state => {
|
|
2067
|
+
return handleClickRefreshDependencies.refresh(state);
|
|
2068
|
+
};
|
|
2069
|
+
|
|
2070
|
+
const handleCloseDetails = state => {
|
|
2071
|
+
return {
|
|
2072
|
+
...state,
|
|
2073
|
+
selectedEvent: null,
|
|
2074
|
+
selectedEventId: null,
|
|
2075
|
+
selectedEventIndex: null
|
|
2076
|
+
};
|
|
2077
|
+
};
|
|
2078
|
+
|
|
2079
|
+
const handleDetailsContextMenu = state => {
|
|
2080
|
+
return state;
|
|
2081
|
+
};
|
|
2082
|
+
|
|
2083
|
+
const handleDetailTab = (state, value) => {
|
|
2084
|
+
if (!isDetailTab(value)) {
|
|
2085
|
+
return state;
|
|
2086
|
+
}
|
|
2087
|
+
return {
|
|
2088
|
+
...state,
|
|
2089
|
+
selectedDetailTab: value
|
|
2090
|
+
};
|
|
2091
|
+
};
|
|
2092
|
+
|
|
2093
|
+
const getCurrentEvents$2 = state => {
|
|
2094
|
+
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
2095
|
+
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
2096
|
+
};
|
|
2097
|
+
const getEventIndexByStableId$1 = (events, event) => {
|
|
2098
|
+
const stableEventId = getStableEventId(event);
|
|
2099
|
+
return events.findIndex(candidate => getStableEventId(candidate) === stableEventId);
|
|
2100
|
+
};
|
|
2101
|
+
const getSelectedEventIndex$1 = state => {
|
|
2102
|
+
const {
|
|
2103
|
+
selectedEventIndex
|
|
2104
|
+
} = state;
|
|
2105
|
+
if (selectedEventIndex === null) {
|
|
2106
|
+
return null;
|
|
2107
|
+
}
|
|
2108
|
+
const filteredEvents = getCurrentEvents$2(state);
|
|
2109
|
+
const selectedEvent = filteredEvents[selectedEventIndex];
|
|
2110
|
+
if (!selectedEvent) {
|
|
2111
|
+
return null;
|
|
2112
|
+
}
|
|
2113
|
+
const newIndex = getEventIndexByStableId$1(filteredEvents, selectedEvent);
|
|
2114
|
+
if (newIndex === -1) {
|
|
2115
|
+
return null;
|
|
2116
|
+
}
|
|
2117
|
+
return newIndex;
|
|
2118
|
+
};
|
|
2119
|
+
const getPreservedSelectedEventIndex$1 = (oldState, newState) => {
|
|
2120
|
+
const {
|
|
2121
|
+
selectedEventIndex
|
|
2122
|
+
} = oldState;
|
|
2123
|
+
if (selectedEventIndex === null) {
|
|
2124
|
+
return null;
|
|
2125
|
+
}
|
|
2126
|
+
const oldFilteredEvents = getCurrentEvents$2(oldState);
|
|
2127
|
+
const selectedEvent = oldFilteredEvents[selectedEventIndex];
|
|
2128
|
+
if (!selectedEvent) {
|
|
2129
|
+
return null;
|
|
2130
|
+
}
|
|
2131
|
+
const newFilteredEvents = getCurrentEvents$2(newState);
|
|
2132
|
+
const newIndex = getEventIndexByStableId$1(newFilteredEvents, selectedEvent);
|
|
2133
|
+
if (newIndex === -1) {
|
|
2134
|
+
return null;
|
|
2135
|
+
}
|
|
2136
|
+
return newIndex;
|
|
2137
|
+
};
|
|
2138
|
+
const withPreservedSelection$1 = (state, nextState) => {
|
|
2139
|
+
const selectedEventIndex = getPreservedSelectedEventIndex$1(state, nextState);
|
|
2140
|
+
return {
|
|
2141
|
+
...nextState,
|
|
2142
|
+
selectedEvent: selectedEventIndex === null ? null : state.selectedEvent,
|
|
2143
|
+
selectedEventId: selectedEventIndex === null ? null : state.selectedEventId,
|
|
2144
|
+
selectedEventIndex
|
|
2145
|
+
};
|
|
2146
|
+
};
|
|
2147
|
+
|
|
2148
|
+
const handleEventCategoryFilter = (state, value) => {
|
|
2149
|
+
const nextState = {
|
|
2150
|
+
...state,
|
|
2151
|
+
eventCategoryFilter: value || All
|
|
2152
|
+
};
|
|
2153
|
+
return withPreservedSelection$1(state, nextState);
|
|
2154
|
+
};
|
|
2155
|
+
|
|
2156
|
+
const getCurrentEvents$1 = state => {
|
|
2157
|
+
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
2158
|
+
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
2159
|
+
};
|
|
2160
|
+
const selectEventAtIndex = async (state, selectedEventIndex, dependencies) => {
|
|
2161
|
+
const currentEvents = getCurrentEvents$1(state);
|
|
2162
|
+
const selectedEvent = currentEvents[selectedEventIndex];
|
|
2163
|
+
if (!selectedEvent) {
|
|
2164
|
+
return {
|
|
2165
|
+
...state,
|
|
2166
|
+
selectedEvent: null,
|
|
2167
|
+
selectedEventId: null,
|
|
2168
|
+
selectedEventIndex
|
|
2169
|
+
};
|
|
2170
|
+
}
|
|
2171
|
+
if (typeof selectedEvent.eventId !== 'number') {
|
|
2172
|
+
return {
|
|
2173
|
+
...state,
|
|
2174
|
+
selectedEvent,
|
|
2175
|
+
selectedEventId: null,
|
|
2176
|
+
selectedEventIndex
|
|
2177
|
+
};
|
|
2178
|
+
}
|
|
2179
|
+
const selectedEventDetails = await dependencies.loadSelectedEvent(state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionId, state.sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
|
|
2180
|
+
return {
|
|
2181
|
+
...state,
|
|
2182
|
+
selectedEvent: selectedEventDetails ?? selectedEvent,
|
|
2183
|
+
selectedEventId: selectedEvent.eventId,
|
|
2184
|
+
selectedEventIndex
|
|
2185
|
+
};
|
|
2186
|
+
};
|
|
2187
|
+
|
|
2188
|
+
const handleEventRowClickDependencies = {
|
|
2189
|
+
loadSelectedEvent: loadSelectedEvent
|
|
2190
|
+
};
|
|
2191
|
+
const isPrimaryButton = button => {
|
|
2192
|
+
return button === 0;
|
|
2193
|
+
};
|
|
2194
|
+
const parseSelectedEventIndex$1 = value => {
|
|
2195
|
+
const parsed = Number.parseInt(value, 10);
|
|
2196
|
+
if (Number.isNaN(parsed) || parsed < 0) {
|
|
2197
|
+
return null;
|
|
2198
|
+
}
|
|
2199
|
+
return parsed;
|
|
2200
|
+
};
|
|
2201
|
+
const handleEventRowClick = async (state, value, button = 0) => {
|
|
2202
|
+
if (!isPrimaryButton(button)) {
|
|
2203
|
+
return state;
|
|
2204
|
+
}
|
|
2205
|
+
const selectedEventIndex = parseSelectedEventIndex$1(value);
|
|
2206
|
+
if (selectedEventIndex === null) {
|
|
2207
|
+
return state;
|
|
2208
|
+
}
|
|
2209
|
+
return selectEventAtIndex(state, selectedEventIndex, handleEventRowClickDependencies);
|
|
2210
|
+
};
|
|
2211
|
+
|
|
2212
|
+
const handleHeaderContextMenu = state => {
|
|
2213
|
+
return state;
|
|
2214
|
+
};
|
|
2215
|
+
|
|
2216
|
+
const getBoolean = value => {
|
|
2217
|
+
return value === true || value === 'true' || value === 'on' || value === '1';
|
|
2218
|
+
};
|
|
2219
|
+
|
|
2220
|
+
const Filter = 'filter';
|
|
2221
|
+
const EventCategoryFilter = 'eventCategoryFilter';
|
|
2222
|
+
const ShowEventStreamFinishedEvents = 'showEventStreamFinishedEvents';
|
|
2223
|
+
const ShowInputEvents = 'showInputEvents';
|
|
2224
|
+
const ShowResponsePartEvents = 'showResponsePartEvents';
|
|
2225
|
+
const UseDevtoolsLayout = 'useDevtoolsLayout';
|
|
2226
|
+
const SelectedEventIndex = 'selectedEventIndex';
|
|
2227
|
+
const CloseDetails = 'closeDetails';
|
|
2228
|
+
const DetailTab = 'detailTab';
|
|
2229
|
+
const TimelineStartSeconds = 'timelineStartSeconds';
|
|
2230
|
+
const TimelineEndSeconds = 'timelineEndSeconds';
|
|
2231
|
+
const TimelineRangePreset = 'timelineRangePreset';
|
|
2232
|
+
const Refresh = 'refresh';
|
|
2233
|
+
|
|
2234
|
+
const getCurrentEvents = state => {
|
|
2235
|
+
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
2236
|
+
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
2237
|
+
};
|
|
2238
|
+
const parseTimelineRangePreset$1 = value => {
|
|
2239
|
+
if (!value) {
|
|
2240
|
+
return {
|
|
2241
|
+
timelineEndSeconds: '',
|
|
2242
|
+
timelineStartSeconds: ''
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
const [timelineStartSeconds = '', timelineEndSeconds = ''] = value.split(':', 2);
|
|
2246
|
+
return {
|
|
2247
|
+
timelineEndSeconds,
|
|
2248
|
+
timelineStartSeconds
|
|
2249
|
+
};
|
|
2250
|
+
};
|
|
2251
|
+
const getEventIndexByStableId = (events, event) => {
|
|
2252
|
+
const stableEventId = getStableEventId(event);
|
|
2253
|
+
return events.findIndex(candidate => getStableEventId(candidate) === stableEventId);
|
|
2254
|
+
};
|
|
2255
|
+
const getSelectedEventIndex = state => {
|
|
2256
|
+
const {
|
|
2257
|
+
selectedEventIndex
|
|
2258
|
+
} = state;
|
|
2259
|
+
if (selectedEventIndex === null) {
|
|
2260
|
+
return null;
|
|
2261
|
+
}
|
|
2262
|
+
const filteredEvents = getCurrentEvents(state);
|
|
2263
|
+
const selectedEvent = filteredEvents[selectedEventIndex];
|
|
2264
|
+
if (!selectedEvent) {
|
|
2265
|
+
return null;
|
|
2266
|
+
}
|
|
2067
2267
|
const newIndex = getEventIndexByStableId(filteredEvents, selectedEvent);
|
|
2068
2268
|
if (newIndex === -1) {
|
|
2069
2269
|
return null;
|
|
@@ -2077,12 +2277,12 @@ const getPreservedSelectedEventIndex = (oldState, newState) => {
|
|
|
2077
2277
|
if (selectedEventIndex === null) {
|
|
2078
2278
|
return null;
|
|
2079
2279
|
}
|
|
2080
|
-
const oldFilteredEvents = getCurrentEvents
|
|
2280
|
+
const oldFilteredEvents = getCurrentEvents(oldState);
|
|
2081
2281
|
const selectedEvent = oldFilteredEvents[selectedEventIndex];
|
|
2082
2282
|
if (!selectedEvent) {
|
|
2083
2283
|
return null;
|
|
2084
2284
|
}
|
|
2085
|
-
const newFilteredEvents = getCurrentEvents
|
|
2285
|
+
const newFilteredEvents = getCurrentEvents(newState);
|
|
2086
2286
|
const newIndex = getEventIndexByStableId(newFilteredEvents, selectedEvent);
|
|
2087
2287
|
if (newIndex === -1) {
|
|
2088
2288
|
return null;
|
|
@@ -2217,7 +2417,44 @@ const handleSashPointerUp = (state, eventX, eventY) => {
|
|
|
2217
2417
|
return state;
|
|
2218
2418
|
};
|
|
2219
2419
|
|
|
2220
|
-
const
|
|
2420
|
+
const devtoolsRootGap = 4;
|
|
2421
|
+
const devtoolsTopHeight = 28;
|
|
2422
|
+
const devtoolsTimelineHeight = 88;
|
|
2423
|
+
const devtoolsTableHeaderHeight = 24;
|
|
2424
|
+
const devtoolsTableRowHeight = 24;
|
|
2425
|
+
const MenuChatDebugTableBody = 2190;
|
|
2426
|
+
const getTableBodyY = (state, hasTimeline) => {
|
|
2427
|
+
return state.y + viewPadding + devtoolsTopHeight + devtoolsRootGap + (hasTimeline ? devtoolsTimelineHeight : 0) + devtoolsTableHeaderHeight;
|
|
2428
|
+
};
|
|
2429
|
+
const getTableBodyEventIndex = (state, eventX, eventY) => {
|
|
2430
|
+
if (!state.useDevtoolsLayout) {
|
|
2431
|
+
return -1;
|
|
2432
|
+
}
|
|
2433
|
+
const currentEvents = getCurrentEvents$1(state);
|
|
2434
|
+
if (currentEvents.length === 0) {
|
|
2435
|
+
return -1;
|
|
2436
|
+
}
|
|
2437
|
+
const tableX = state.x + leftPadding;
|
|
2438
|
+
const tableWidth = clampTableWidth(state.width, state.tableWidth);
|
|
2439
|
+
const hasTimeline = currentEvents.length > 0;
|
|
2440
|
+
const tableBodyY = getTableBodyY(state, hasTimeline);
|
|
2441
|
+
const relativeX = eventX - tableX;
|
|
2442
|
+
const relativeY = eventY - tableBodyY;
|
|
2443
|
+
if (relativeX < 0 || relativeX >= tableWidth || relativeY < 0) {
|
|
2444
|
+
return -1;
|
|
2445
|
+
}
|
|
2446
|
+
const eventIndex = Math.floor(relativeY / devtoolsTableRowHeight);
|
|
2447
|
+
if (eventIndex < 0 || eventIndex >= currentEvents.length) {
|
|
2448
|
+
return -1;
|
|
2449
|
+
}
|
|
2450
|
+
return eventIndex;
|
|
2451
|
+
};
|
|
2452
|
+
const handleTableBodyContextMenu = async (state, eventX, eventY) => {
|
|
2453
|
+
const eventIndex = getTableBodyEventIndex(state, eventX, eventY);
|
|
2454
|
+
await showContextMenu2(state.uid, MenuChatDebugTableBody, eventX, eventY, {
|
|
2455
|
+
eventIndex,
|
|
2456
|
+
menuId: MenuChatDebugTableBody
|
|
2457
|
+
});
|
|
2221
2458
|
return state;
|
|
2222
2459
|
};
|
|
2223
2460
|
|
|
@@ -2246,1258 +2483,181 @@ const parseTimelineRangePreset = value => {
|
|
|
2246
2483
|
const handleTimelineStartSeconds = (state, value) => {
|
|
2247
2484
|
const nextState = {
|
|
2248
2485
|
...state,
|
|
2249
|
-
timelineStartSeconds: value
|
|
2250
|
-
};
|
|
2251
|
-
return withPreservedSelection$1(state, nextState);
|
|
2252
|
-
};
|
|
2253
|
-
const handleTimelineEndSeconds = (state, value) => {
|
|
2254
|
-
const nextState = {
|
|
2255
|
-
...state,
|
|
2256
|
-
timelineEndSeconds: value
|
|
2257
|
-
};
|
|
2258
|
-
return withPreservedSelection$1(state, nextState);
|
|
2259
|
-
};
|
|
2260
|
-
const handleTimelineRangePreset = (state, value) => {
|
|
2261
|
-
const nextState = {
|
|
2262
|
-
...state,
|
|
2263
|
-
...parseTimelineRangePreset(value)
|
|
2264
|
-
};
|
|
2265
|
-
return withPreservedSelection$1(state, nextState);
|
|
2266
|
-
};
|
|
2267
|
-
|
|
2268
|
-
const handleTimelineDoubleClick = state => {
|
|
2269
|
-
const nextState = handleTimelineRangePreset(state, '');
|
|
2270
|
-
return clearTimelineSelectionState(nextState);
|
|
2271
|
-
};
|
|
2272
|
-
|
|
2273
|
-
const getTimelineEvents = state => {
|
|
2274
|
-
const {
|
|
2275
|
-
eventCategoryFilter,
|
|
2276
|
-
events,
|
|
2277
|
-
filterValue,
|
|
2278
|
-
showEventStreamFinishedEvents,
|
|
2279
|
-
showInputEvents,
|
|
2280
|
-
showResponsePartEvents
|
|
2281
|
-
} = state;
|
|
2282
|
-
return getFilteredEvents(events, filterValue, eventCategoryFilter, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents);
|
|
2283
|
-
};
|
|
2284
|
-
|
|
2285
|
-
const getTimelineLeft = state => {
|
|
2286
|
-
return state.x + viewPadding + timelineHorizontalPadding;
|
|
2287
|
-
};
|
|
2288
|
-
const getTimelineWidth = state => {
|
|
2289
|
-
return Math.max(0, getMainWidth(state.width) - timelineHorizontalPadding * 2);
|
|
2290
|
-
};
|
|
2291
|
-
|
|
2292
|
-
const trailingZeroFractionRegex = /\.0+$/;
|
|
2293
|
-
const trailingFractionZeroRegex = /(\.\d*?)0+$/;
|
|
2294
|
-
const formatTimelinePresetValue = value => {
|
|
2295
|
-
return value.toFixed(3).replace(trailingZeroFractionRegex, '').replace(trailingFractionZeroRegex, '$1');
|
|
2296
|
-
};
|
|
2297
|
-
|
|
2298
|
-
const getTimelineSecondsFromClientX = (events, eventX, timelineLeft, timelineWidth) => {
|
|
2299
|
-
if (timelineWidth <= 0) {
|
|
2300
|
-
return undefined;
|
|
2301
|
-
}
|
|
2302
|
-
const durationSeconds = getTimelineDurationSeconds(events);
|
|
2303
|
-
const relativeX = Math.min(Math.max(eventX - timelineLeft, 0), timelineWidth);
|
|
2304
|
-
const ratio = relativeX / timelineWidth;
|
|
2305
|
-
return formatTimelinePresetValue(durationSeconds * ratio);
|
|
2306
|
-
};
|
|
2307
|
-
|
|
2308
|
-
const handleTimelinePointerDown = (state, eventX) => {
|
|
2309
|
-
const timelineEvents = getTimelineEvents(state);
|
|
2310
|
-
const timelineLeft = getTimelineLeft(state);
|
|
2311
|
-
const timelineWidth = getTimelineWidth(state);
|
|
2312
|
-
const clientX = state.x + eventX;
|
|
2313
|
-
const seconds = getTimelineSecondsFromClientX(timelineEvents, clientX, timelineLeft, timelineWidth);
|
|
2314
|
-
if (seconds === undefined) {
|
|
2315
|
-
return state;
|
|
2316
|
-
}
|
|
2317
|
-
return {
|
|
2318
|
-
...state,
|
|
2319
|
-
timelineSelectionActive: true,
|
|
2320
|
-
timelineSelectionAnchorSeconds: seconds,
|
|
2321
|
-
timelineSelectionFocusSeconds: seconds
|
|
2322
|
-
};
|
|
2323
|
-
};
|
|
2324
|
-
|
|
2325
|
-
const handleTimelinePointerMove = (state, eventX) => {
|
|
2326
|
-
if (!state.timelineSelectionActive) {
|
|
2327
|
-
return state;
|
|
2328
|
-
}
|
|
2329
|
-
const timelineEvents = getTimelineEvents(state);
|
|
2330
|
-
const timelineLeft = getTimelineLeft(state);
|
|
2331
|
-
const timelineWidth = getTimelineWidth(state);
|
|
2332
|
-
const clientX = state.x + eventX;
|
|
2333
|
-
const seconds = getTimelineSecondsFromClientX(timelineEvents, clientX, timelineLeft, timelineWidth);
|
|
2334
|
-
if (seconds === undefined) {
|
|
2335
|
-
return state;
|
|
2336
|
-
}
|
|
2337
|
-
return {
|
|
2338
|
-
...state,
|
|
2339
|
-
timelineSelectionFocusSeconds: seconds
|
|
2340
|
-
};
|
|
2341
|
-
};
|
|
2342
|
-
|
|
2343
|
-
const handleTimelinePointerUp = (state, eventX) => {
|
|
2344
|
-
if (!state.timelineSelectionActive) {
|
|
2345
|
-
return state;
|
|
2346
|
-
}
|
|
2347
|
-
const timelineEvents = getTimelineEvents(state);
|
|
2348
|
-
const timelineLeft = getTimelineLeft(state);
|
|
2349
|
-
const timelineWidth = getTimelineWidth(state);
|
|
2350
|
-
const clientX = state.x + eventX;
|
|
2351
|
-
const focusSeconds = getTimelineSecondsFromClientX(timelineEvents, clientX, timelineLeft, timelineWidth);
|
|
2352
|
-
if (focusSeconds === undefined) {
|
|
2353
|
-
return clearTimelineSelectionState(state);
|
|
2354
|
-
}
|
|
2355
|
-
const anchor = Number.parseFloat(state.timelineSelectionAnchorSeconds);
|
|
2356
|
-
const focus = Number.parseFloat(focusSeconds);
|
|
2357
|
-
const startSeconds = formatTimelinePresetValue(Math.min(anchor, focus));
|
|
2358
|
-
const endSeconds = formatTimelinePresetValue(Math.max(anchor, focus));
|
|
2359
|
-
const nextState = handleTimelineRangePreset(state, `${startSeconds}:${endSeconds}`);
|
|
2360
|
-
return clearTimelineSelectionState(nextState);
|
|
2361
|
-
};
|
|
2362
|
-
|
|
2363
|
-
const handleUseDevtoolsLayout = (state, checked) => {
|
|
2364
|
-
const useDevtoolsLayout = getBoolean(checked);
|
|
2365
|
-
const selectedEventIndex = useDevtoolsLayout ? getSelectedEventIndex$1(state) : null;
|
|
2366
|
-
return {
|
|
2367
|
-
...state,
|
|
2368
|
-
selectedEvent: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEvent : null,
|
|
2369
|
-
selectedEventId: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEventId : null,
|
|
2370
|
-
selectedEventIndex,
|
|
2371
|
-
useDevtoolsLayout
|
|
2372
|
-
};
|
|
2373
|
-
};
|
|
2374
|
-
|
|
2375
|
-
const handleShowEventStreamFinishedEvents = (state, checked) => {
|
|
2376
|
-
const nextState = {
|
|
2377
|
-
...state,
|
|
2378
|
-
showEventStreamFinishedEvents: getBoolean(checked)
|
|
2379
|
-
};
|
|
2380
|
-
return withPreservedSelection$1(state, nextState);
|
|
2381
|
-
};
|
|
2382
|
-
const handleShowInputEvents = (state, checked) => {
|
|
2383
|
-
const nextState = {
|
|
2384
|
-
...state,
|
|
2385
|
-
showInputEvents: getBoolean(checked)
|
|
2386
|
-
};
|
|
2387
|
-
return withPreservedSelection$1(state, nextState);
|
|
2388
|
-
};
|
|
2389
|
-
const handleShowResponsePartEvents = (state, checked) => {
|
|
2390
|
-
const nextState = {
|
|
2391
|
-
...state,
|
|
2392
|
-
showResponsePartEvents: getBoolean(checked)
|
|
2393
|
-
};
|
|
2394
|
-
return withPreservedSelection$1(state, nextState);
|
|
2395
|
-
};
|
|
2396
|
-
|
|
2397
|
-
const getFailedToLoadMessage = sessionId => {
|
|
2398
|
-
return `Failed to load chat debug session "${sessionId}". Please try again.`;
|
|
2399
|
-
};
|
|
2400
|
-
|
|
2401
|
-
const getIndexedDbNotSupportedMessage = () => {
|
|
2402
|
-
return 'Unable to load chat debug session: IndexedDB is not supported in this environment.';
|
|
2403
|
-
};
|
|
2404
|
-
|
|
2405
|
-
const ParseChatDebugUriErrorCode = {
|
|
2406
|
-
InvalidSessionId: 'invalid-session-id',
|
|
2407
|
-
InvalidUriEncoding: 'invalid-uri-encoding',
|
|
2408
|
-
InvalidUriFormat: 'invalid-uri-format',
|
|
2409
|
-
MissingUri: 'missing-uri'
|
|
2410
|
-
};
|
|
2411
|
-
|
|
2412
|
-
const getInvalidUriMessage = (uri, code) => {
|
|
2413
|
-
if (code === ParseChatDebugUriErrorCode.MissingUri) {
|
|
2414
|
-
return 'Unable to load debug session: missing URI. Expected format: chat-debug://<sessionId>.';
|
|
2415
|
-
}
|
|
2416
|
-
return `Unable to load debug session: invalid URI "${uri}". Expected format: chat-debug://<sessionId>.`;
|
|
2417
|
-
};
|
|
2418
|
-
|
|
2419
|
-
const getSessionNotFoundMessage = sessionId => {
|
|
2420
|
-
return `No chat session found for sessionId "${sessionId}".`;
|
|
2421
|
-
};
|
|
2422
|
-
|
|
2423
|
-
const filterEventsBySessionId = (events, sessionId) => {
|
|
2424
|
-
return events.filter(event => event.sessionId === sessionId);
|
|
2425
|
-
};
|
|
2426
|
-
|
|
2427
|
-
// cspell:ignore IDBP
|
|
2428
|
-
|
|
2429
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
2430
|
-
const getAllEvents = async store => {
|
|
2431
|
-
const all = await store.getAll();
|
|
2432
|
-
return all;
|
|
2433
|
-
};
|
|
2434
|
-
|
|
2435
|
-
const getEndTime = event => {
|
|
2436
|
-
return event.ended ?? event.endTime ?? event.timestamp;
|
|
2437
|
-
};
|
|
2438
|
-
|
|
2439
|
-
const getStartTime = event => {
|
|
2440
|
-
return event.started ?? event.startTime ?? event.timestamp;
|
|
2441
|
-
};
|
|
2442
|
-
|
|
2443
|
-
const getDuration = event => {
|
|
2444
|
-
const explicitDuration = event.durationMs ?? event.duration;
|
|
2445
|
-
if (typeof explicitDuration === 'number' && Number.isFinite(explicitDuration)) {
|
|
2446
|
-
return explicitDuration;
|
|
2447
|
-
}
|
|
2448
|
-
const start = toTimeNumber(getStartTime(event));
|
|
2449
|
-
const end = toTimeNumber(getEndTime(event));
|
|
2450
|
-
if (start === undefined || end === undefined || !Number.isFinite(start) || !Number.isFinite(end)) {
|
|
2451
|
-
return 0;
|
|
2452
|
-
}
|
|
2453
|
-
return Math.max(0, end - start);
|
|
2454
|
-
};
|
|
2455
|
-
|
|
2456
|
-
const isTimeValue = value => {
|
|
2457
|
-
return typeof value === 'number' || typeof value === 'string';
|
|
2458
|
-
};
|
|
2459
|
-
|
|
2460
|
-
const getLightweightEvent = (event, fallbackEventId) => {
|
|
2461
|
-
const startTime = getStartTime(event);
|
|
2462
|
-
const endTime = getEndTime(event);
|
|
2463
|
-
return {
|
|
2464
|
-
duration: getDuration(event),
|
|
2465
|
-
...(isTimeValue(endTime) ? {
|
|
2466
|
-
endTime
|
|
2467
|
-
} : {}),
|
|
2468
|
-
eventId: typeof event.eventId === 'number' ? event.eventId : fallbackEventId,
|
|
2469
|
-
...(isTimeValue(startTime) ? {
|
|
2470
|
-
startTime
|
|
2471
|
-
} : {}),
|
|
2472
|
-
type: event.type
|
|
2473
|
-
};
|
|
2474
|
-
};
|
|
2475
|
-
|
|
2476
|
-
// cspell:ignore IDBP
|
|
2477
|
-
|
|
2478
|
-
const toLightweightEvents = events => {
|
|
2479
|
-
const eventsWithIds = events.map((event, index) => {
|
|
2480
|
-
return {
|
|
2481
|
-
...event,
|
|
2482
|
-
eventId: index + 1
|
|
2483
|
-
};
|
|
2484
|
-
});
|
|
2485
|
-
return collapseToolExecutionEvents(eventsWithIds).map((event, index) => getLightweightEvent(event, index + 1));
|
|
2486
|
-
};
|
|
2487
|
-
const getEventsBySessionId = async (store, sessionId, sessionIdIndexName) => {
|
|
2488
|
-
if (store.indexNames.contains(sessionIdIndexName)) {
|
|
2489
|
-
const index = store.index(sessionIdIndexName);
|
|
2490
|
-
const events = await index.getAll(sessionId);
|
|
2491
|
-
return toLightweightEvents(filterEventsBySessionId(events, sessionId));
|
|
2492
|
-
}
|
|
2493
|
-
const all = await getAllEvents(store);
|
|
2494
|
-
return toLightweightEvents(filterEventsBySessionId(all, sessionId));
|
|
2495
|
-
};
|
|
2496
|
-
|
|
2497
|
-
let indexedDbSupportOverride;
|
|
2498
|
-
const getIndexedDbSupportOverride = () => {
|
|
2499
|
-
return indexedDbSupportOverride;
|
|
2500
|
-
};
|
|
2501
|
-
const setIndexedDbSupportOverride = supported => {
|
|
2502
|
-
indexedDbSupportOverride = supported;
|
|
2503
|
-
};
|
|
2504
|
-
|
|
2505
|
-
const isIndexedDbSupported = indexedDbSupportOverride => {
|
|
2506
|
-
if (typeof indexedDbSupportOverride === 'boolean') {
|
|
2507
|
-
return indexedDbSupportOverride;
|
|
2508
|
-
}
|
|
2509
|
-
const override = getIndexedDbSupportOverride();
|
|
2510
|
-
if (typeof override === 'boolean') {
|
|
2511
|
-
return override;
|
|
2512
|
-
}
|
|
2513
|
-
return globalThis.indexedDB !== undefined;
|
|
2514
|
-
};
|
|
2515
|
-
|
|
2516
|
-
const listChatViewEventsDependencies = {
|
|
2517
|
-
getEventsBySessionId: getEventsBySessionId,
|
|
2518
|
-
listChatViewEventsFromWorker: listChatViewEvents$1,
|
|
2519
|
-
openDatabase: openDatabase
|
|
2520
|
-
};
|
|
2521
|
-
const listChatViewEvents = async (sessionId, databaseName, dataBaseVersion, eventStoreName, sessionIdIndexName, indexedDbSupportOverride) => {
|
|
2522
|
-
if (!isIndexedDbSupported(indexedDbSupportOverride)) {
|
|
2523
|
-
return {
|
|
2524
|
-
type: 'not-supported'
|
|
2525
|
-
};
|
|
2526
|
-
}
|
|
2527
|
-
try {
|
|
2528
|
-
const database = await listChatViewEventsDependencies.openDatabase(databaseName, dataBaseVersion);
|
|
2529
|
-
try {
|
|
2530
|
-
if (!database.objectStoreNames.contains(eventStoreName)) {
|
|
2531
|
-
return {
|
|
2532
|
-
events: [],
|
|
2533
|
-
type: 'success'
|
|
2534
|
-
};
|
|
2535
|
-
}
|
|
2536
|
-
const transaction = database.transaction(eventStoreName, 'readonly');
|
|
2537
|
-
const store = transaction.objectStore(eventStoreName);
|
|
2538
|
-
if (!sessionId) {
|
|
2539
|
-
return {
|
|
2540
|
-
events: [],
|
|
2541
|
-
type: 'success'
|
|
2542
|
-
};
|
|
2543
|
-
}
|
|
2544
|
-
const events = await listChatViewEventsDependencies.getEventsBySessionId(store, sessionId, sessionIdIndexName);
|
|
2545
|
-
return {
|
|
2546
|
-
events,
|
|
2547
|
-
type: 'success'
|
|
2548
|
-
};
|
|
2549
|
-
} finally {
|
|
2550
|
-
database.close();
|
|
2551
|
-
}
|
|
2552
|
-
} catch (error) {
|
|
2553
|
-
return {
|
|
2554
|
-
error,
|
|
2555
|
-
type: 'error'
|
|
2556
|
-
};
|
|
2557
|
-
}
|
|
2558
|
-
};
|
|
2559
|
-
|
|
2560
|
-
const chatDebugUriPattern = /^chat-debug:\/\/([^/?#]+)$/;
|
|
2561
|
-
const invalidSessionIdPattern = /[/?#]/;
|
|
2562
|
-
const parseChatDebugUri = uri => {
|
|
2563
|
-
if (!uri) {
|
|
2564
|
-
return {
|
|
2565
|
-
code: ParseChatDebugUriErrorCode.MissingUri,
|
|
2566
|
-
message: 'Missing URI',
|
|
2567
|
-
type: 'error'
|
|
2568
|
-
};
|
|
2569
|
-
}
|
|
2570
|
-
const match = uri.match(chatDebugUriPattern);
|
|
2571
|
-
if (!match) {
|
|
2572
|
-
return {
|
|
2573
|
-
code: ParseChatDebugUriErrorCode.InvalidUriFormat,
|
|
2574
|
-
message: 'Invalid URI format',
|
|
2575
|
-
type: 'error'
|
|
2576
|
-
};
|
|
2577
|
-
}
|
|
2578
|
-
const encodedSessionId = match[1];
|
|
2579
|
-
let sessionId;
|
|
2580
|
-
try {
|
|
2581
|
-
sessionId = decodeURIComponent(encodedSessionId);
|
|
2582
|
-
} catch {
|
|
2583
|
-
return {
|
|
2584
|
-
code: ParseChatDebugUriErrorCode.InvalidUriEncoding,
|
|
2585
|
-
message: 'Invalid URI encoding',
|
|
2586
|
-
type: 'error'
|
|
2587
|
-
};
|
|
2588
|
-
}
|
|
2589
|
-
if (!sessionId || invalidSessionIdPattern.test(sessionId)) {
|
|
2590
|
-
return {
|
|
2591
|
-
code: ParseChatDebugUriErrorCode.InvalidSessionId,
|
|
2592
|
-
message: 'Invalid session id',
|
|
2593
|
-
type: 'error'
|
|
2594
|
-
};
|
|
2595
|
-
}
|
|
2596
|
-
return {
|
|
2597
|
-
sessionId,
|
|
2598
|
-
type: 'success'
|
|
2599
|
-
};
|
|
2600
|
-
};
|
|
2601
|
-
|
|
2602
|
-
const loadEventsDependencies = {
|
|
2603
|
-
listChatViewEvents: listChatViewEvents,
|
|
2604
|
-
loadSelectedEvent: loadSelectedEvent
|
|
2605
|
-
};
|
|
2606
|
-
const getCurrentEvents = state => {
|
|
2607
|
-
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
2608
|
-
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
2609
|
-
};
|
|
2610
|
-
const restoreSelectedEvent = async state => {
|
|
2611
|
-
if (state.selectedEventId === null) {
|
|
2612
|
-
return {
|
|
2613
|
-
...state,
|
|
2614
|
-
selectedEvent: null,
|
|
2615
|
-
selectedEventIndex: null
|
|
2616
|
-
};
|
|
2617
|
-
}
|
|
2618
|
-
const currentEvents = getCurrentEvents(state);
|
|
2619
|
-
const selectedEventIndex = currentEvents.findIndex(event => event.eventId === state.selectedEventId);
|
|
2620
|
-
if (selectedEventIndex === -1) {
|
|
2621
|
-
return {
|
|
2622
|
-
...state,
|
|
2623
|
-
selectedEvent: null,
|
|
2624
|
-
selectedEventId: null,
|
|
2625
|
-
selectedEventIndex: null
|
|
2626
|
-
};
|
|
2627
|
-
}
|
|
2628
|
-
const selectedEvent = currentEvents[selectedEventIndex];
|
|
2629
|
-
if (!selectedEvent || typeof selectedEvent.eventId !== 'number') {
|
|
2630
|
-
return {
|
|
2631
|
-
...state,
|
|
2632
|
-
selectedEvent: null,
|
|
2633
|
-
selectedEventId: null,
|
|
2634
|
-
selectedEventIndex: null
|
|
2635
|
-
};
|
|
2636
|
-
}
|
|
2637
|
-
const selectedEventDetails = await loadEventsDependencies.loadSelectedEvent(state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionId, state.sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
|
|
2638
|
-
return {
|
|
2639
|
-
...state,
|
|
2640
|
-
selectedEvent: selectedEventDetails,
|
|
2641
|
-
selectedEventId: selectedEvent.eventId,
|
|
2642
|
-
selectedEventIndex
|
|
2643
|
-
};
|
|
2644
|
-
};
|
|
2645
|
-
const getStateWithInvalidUri = state => {
|
|
2646
|
-
const parsed = parseChatDebugUri(state.uri);
|
|
2647
|
-
if (parsed.type !== 'error') {
|
|
2648
|
-
return state;
|
|
2649
|
-
}
|
|
2650
|
-
return {
|
|
2651
|
-
...state,
|
|
2652
|
-
errorMessage: getInvalidUriMessage(state.uri, parsed.code),
|
|
2653
|
-
events: [],
|
|
2654
|
-
initial: false,
|
|
2655
|
-
selectedEvent: null,
|
|
2656
|
-
selectedEventId: null,
|
|
2657
|
-
selectedEventIndex: null,
|
|
2658
|
-
sessionId: ''
|
|
2659
|
-
};
|
|
2660
|
-
};
|
|
2661
|
-
const getSessionIdFromUri = state => {
|
|
2662
|
-
const parsed = parseChatDebugUri(state.uri);
|
|
2663
|
-
if (parsed.type === 'error') {
|
|
2664
|
-
return undefined;
|
|
2665
|
-
}
|
|
2666
|
-
return parsed.sessionId;
|
|
2667
|
-
};
|
|
2668
|
-
const loadEventsForSessionId = async (state, sessionId) => {
|
|
2669
|
-
const {
|
|
2670
|
-
databaseName,
|
|
2671
|
-
dataBaseVersion,
|
|
2672
|
-
eventStoreName,
|
|
2673
|
-
indexedDbSupportOverride,
|
|
2674
|
-
sessionIdIndexName
|
|
2675
|
-
} = state;
|
|
2676
|
-
const result = await loadEventsDependencies.listChatViewEvents(sessionId, databaseName, dataBaseVersion, eventStoreName, sessionIdIndexName, indexedDbSupportOverride);
|
|
2677
|
-
if (result.type === 'not-supported') {
|
|
2678
|
-
return {
|
|
2679
|
-
...state,
|
|
2680
|
-
errorMessage: getIndexedDbNotSupportedMessage(),
|
|
2681
|
-
events: [],
|
|
2682
|
-
initial: false,
|
|
2683
|
-
selectedEvent: null,
|
|
2684
|
-
selectedEventId: null,
|
|
2685
|
-
selectedEventIndex: null,
|
|
2686
|
-
sessionId
|
|
2687
|
-
};
|
|
2688
|
-
}
|
|
2689
|
-
if (result.type === 'error') {
|
|
2690
|
-
return {
|
|
2691
|
-
...state,
|
|
2692
|
-
errorMessage: getFailedToLoadMessage(sessionId),
|
|
2693
|
-
events: [],
|
|
2694
|
-
initial: false,
|
|
2695
|
-
selectedEvent: null,
|
|
2696
|
-
selectedEventId: null,
|
|
2697
|
-
selectedEventIndex: null,
|
|
2698
|
-
sessionId
|
|
2699
|
-
};
|
|
2700
|
-
}
|
|
2701
|
-
const {
|
|
2702
|
-
events
|
|
2703
|
-
} = result;
|
|
2704
|
-
if (events.length === 0) {
|
|
2705
|
-
return {
|
|
2706
|
-
...state,
|
|
2707
|
-
errorMessage: getSessionNotFoundMessage(sessionId),
|
|
2708
|
-
events: [],
|
|
2709
|
-
initial: false,
|
|
2710
|
-
selectedEvent: null,
|
|
2711
|
-
selectedEventId: null,
|
|
2712
|
-
selectedEventIndex: null,
|
|
2713
|
-
sessionId
|
|
2714
|
-
};
|
|
2715
|
-
}
|
|
2716
|
-
const nextState = {
|
|
2717
|
-
...state,
|
|
2718
|
-
errorMessage: '',
|
|
2719
|
-
events,
|
|
2720
|
-
initial: false,
|
|
2721
|
-
sessionId
|
|
2722
|
-
};
|
|
2723
|
-
return restoreSelectedEvent(nextState);
|
|
2724
|
-
};
|
|
2725
|
-
const loadEventsFromUri = async state => {
|
|
2726
|
-
const sessionId = getSessionIdFromUri(state);
|
|
2727
|
-
if (!sessionId) {
|
|
2728
|
-
return getStateWithInvalidUri(state);
|
|
2729
|
-
}
|
|
2730
|
-
return loadEventsForSessionId(state, sessionId);
|
|
2731
|
-
};
|
|
2732
|
-
const refreshEvents = async state => {
|
|
2733
|
-
const sessionId = state.sessionId || getSessionIdFromUri(state);
|
|
2734
|
-
if (!sessionId) {
|
|
2735
|
-
return getStateWithInvalidUri(state);
|
|
2736
|
-
}
|
|
2737
|
-
return loadEventsForSessionId(state, sessionId);
|
|
2738
|
-
};
|
|
2739
|
-
|
|
2740
|
-
const loadContent = async state => {
|
|
2741
|
-
return loadEventsFromUri(state);
|
|
2742
|
-
};
|
|
2743
|
-
|
|
2744
|
-
const refresh = async state => {
|
|
2745
|
-
return refreshEvents(state);
|
|
2746
|
-
};
|
|
2747
|
-
|
|
2748
|
-
const Button = 1;
|
|
2749
|
-
const Div = 4;
|
|
2750
|
-
const Input = 6;
|
|
2751
|
-
const Span = 8;
|
|
2752
|
-
const Table = 9;
|
|
2753
|
-
const TBody = 10;
|
|
2754
|
-
const Td = 11;
|
|
2755
|
-
const Text = 12;
|
|
2756
|
-
const Th = 13;
|
|
2757
|
-
const THead = 14;
|
|
2758
|
-
const Tr = 15;
|
|
2759
|
-
const Search = 42;
|
|
2760
|
-
const Label = 66;
|
|
2761
|
-
const Reference = 100;
|
|
2762
|
-
|
|
2763
|
-
const ClientX = 'event.clientX';
|
|
2764
|
-
const ClientY = 'event.clientY';
|
|
2765
|
-
const TargetName = 'event.target.name';
|
|
2766
|
-
const TargetValue = 'event.target.value';
|
|
2767
|
-
|
|
2768
|
-
const SetCss = 'Viewlet.setCss';
|
|
2769
|
-
const SetDom2 = 'Viewlet.setDom2';
|
|
2770
|
-
const SetPatches = 'Viewlet.setPatches';
|
|
2771
|
-
|
|
2772
|
-
const getCss = state => {
|
|
2773
|
-
const tableWidth = clampTableWidth(state.width, state.tableWidth);
|
|
2774
|
-
const detailsWidth = getDetailsWidth(state.width, state.tableWidth);
|
|
2775
|
-
return `
|
|
2776
|
-
.ChatDebugView {
|
|
2777
|
-
--ChatDebugViewDetailsWidth: ${detailsWidth}px;
|
|
2778
|
-
--ChatDebugViewSashWidth: ${sashWidth}px;
|
|
2779
|
-
--ChatDebugViewTableWidth: ${tableWidth}px;
|
|
2780
|
-
padding: ${viewPadding}px;
|
|
2781
|
-
display: flex;
|
|
2782
|
-
flex-direction: column;
|
|
2783
|
-
height: 100%;
|
|
2784
|
-
box-sizing: border-box;
|
|
2785
|
-
gap: 8px;
|
|
2786
|
-
contain: strict;
|
|
2787
|
-
}
|
|
2788
|
-
|
|
2789
|
-
.ChatDebugView--devtools {
|
|
2790
|
-
gap: 4px;
|
|
2791
|
-
}
|
|
2792
|
-
|
|
2793
|
-
.ChatDebugViewTop {
|
|
2794
|
-
display: flex;
|
|
2795
|
-
align-items: center;
|
|
2796
|
-
gap: 12px;
|
|
2797
|
-
flex-wrap: wrap;
|
|
2798
|
-
contain: content;
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2801
|
-
.ChatDebugViewTop--devtools {
|
|
2802
|
-
align-items: stretch;
|
|
2803
|
-
}
|
|
2804
|
-
|
|
2805
|
-
.ChatDebugViewFilterInput {
|
|
2806
|
-
flex: 1;
|
|
2807
|
-
min-width: 0;
|
|
2808
|
-
max-width: 500px;
|
|
2809
|
-
contain: content;
|
|
2810
|
-
}
|
|
2811
|
-
|
|
2812
|
-
.ChatDebugViewFilterInput--devtools {
|
|
2813
|
-
flex: 0 1 80px;
|
|
2814
|
-
width: 100%;
|
|
2815
|
-
max-width: 80px;
|
|
2816
|
-
}
|
|
2817
|
-
|
|
2818
|
-
.ChatDebugViewQuickFilterPill {
|
|
2819
|
-
display: flex;
|
|
2820
|
-
align-items: center;
|
|
2821
|
-
justify-content: center;
|
|
2822
|
-
min-height: 22px;
|
|
2823
|
-
padding: 0 10px;
|
|
2824
|
-
border: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
2825
|
-
border-radius: 999px;
|
|
2826
|
-
cursor: pointer;
|
|
2827
|
-
white-space: nowrap;
|
|
2828
|
-
transition:
|
|
2829
|
-
background 120ms ease-out,
|
|
2830
|
-
border-color 120ms ease-out,
|
|
2831
|
-
color 120ms ease-out,
|
|
2832
|
-
transform 120ms ease-out;
|
|
2833
|
-
contain: content;
|
|
2834
|
-
}
|
|
2835
|
-
|
|
2836
|
-
.ChatDebugViewQuickFilterPill:not(.ChatDebugViewQuickFilterPillSelected):hover {
|
|
2837
|
-
border-color: var(--vscode-focusBorder, #007fd4);
|
|
2838
|
-
background: color-mix(in srgb, var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.16)) 82%, transparent 18%);
|
|
2839
|
-
color: var(--vscode-list-hoverForeground, inherit);
|
|
2840
|
-
transform: translateY(-1px);
|
|
2841
|
-
}
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
.ChatDebugViewQuickFilters {
|
|
2845
|
-
display: flex;
|
|
2846
|
-
align-items: center;
|
|
2847
|
-
gap: 8px;
|
|
2848
|
-
justify-content: center;
|
|
2849
|
-
min-height: 28px;
|
|
2850
|
-
font-size: 12px;
|
|
2851
|
-
line-height: 1;
|
|
2852
|
-
contain: content;
|
|
2853
|
-
}
|
|
2854
|
-
|
|
2855
|
-
.ChatDebugViewQuickFilterPillSelected {
|
|
2856
|
-
border-color: var(--vscode-focusBorder, #007fd4);
|
|
2857
|
-
background: var(--vscode-list-activeSelectionBackground, rgba(14, 99, 156, 0.35));
|
|
2858
|
-
color: var(--vscode-list-activeSelectionForeground, inherit);
|
|
2859
|
-
}
|
|
2860
|
-
|
|
2861
|
-
.ChatDebugViewQuickFilterInput {
|
|
2862
|
-
position: absolute;
|
|
2863
|
-
opacity: 0;
|
|
2864
|
-
pointer-events: none;
|
|
2865
|
-
contain: content;
|
|
2866
|
-
}
|
|
2867
|
-
|
|
2868
|
-
.ChatDebugViewEvents {
|
|
2869
|
-
display: flex;
|
|
2870
|
-
flex-direction: column;
|
|
2871
|
-
overflow: auto;
|
|
2872
|
-
min-width: 0;
|
|
2873
|
-
min-height: 0;
|
|
2874
|
-
scrollbar-width: thin;
|
|
2875
|
-
scrollbar-color: var(--vscode-scrollbarSlider-background, rgba(121, 121, 121, 0.4)) transparent;
|
|
2876
|
-
contain: strict;
|
|
2877
|
-
}
|
|
2878
|
-
|
|
2879
|
-
.ChatDebugView--devtools .ChatDebugViewEvents {
|
|
2880
|
-
border-radius: 6px;
|
|
2881
|
-
margin-bottom: 0;
|
|
2882
|
-
overflow: hidden;
|
|
2883
|
-
}
|
|
2884
|
-
|
|
2885
|
-
.ChatDebugViewEventsFullWidth {
|
|
2886
|
-
flex: 1 1 100%;
|
|
2887
|
-
}
|
|
2888
|
-
|
|
2889
|
-
.ChatDebugViewDevtoolsMain {
|
|
2890
|
-
display: flex;
|
|
2891
|
-
flex-direction: column;
|
|
2892
|
-
flex: 1;
|
|
2893
|
-
align-items: stretch;
|
|
2894
|
-
gap: 0;
|
|
2895
|
-
min-width: 0;
|
|
2896
|
-
min-height: 0;
|
|
2897
|
-
contain: strict;
|
|
2898
|
-
}
|
|
2899
|
-
|
|
2900
|
-
.ChatDebugViewDevtoolsMain > .ChatDebugViewTimeline {
|
|
2901
|
-
flex: 0 0 auto;
|
|
2902
|
-
}
|
|
2903
|
-
|
|
2904
|
-
.ChatDebugViewDevtoolsSplit {
|
|
2905
|
-
display: flex;
|
|
2906
|
-
flex: 1;
|
|
2907
|
-
align-items: stretch;
|
|
2908
|
-
gap: 0;
|
|
2909
|
-
min-width: 0;
|
|
2910
|
-
min-height: 0;
|
|
2911
|
-
overflow: hidden;
|
|
2912
|
-
contain: strict;
|
|
2913
|
-
}
|
|
2914
|
-
|
|
2915
|
-
.ChatDebugViewDevtoolsSplit > .ChatDebugViewEvents {
|
|
2916
|
-
flex: 0 1 var(--ChatDebugViewTableWidth);
|
|
2917
|
-
min-width: 0;
|
|
2918
|
-
}
|
|
2919
|
-
|
|
2920
|
-
.ChatDebugViewDevtoolsSplit > .ChatDebugViewEvents.ChatDebugViewEventsFullWidth {
|
|
2921
|
-
flex: 1 1 100%;
|
|
2922
|
-
}
|
|
2923
|
-
|
|
2924
|
-
.ChatDebugViewDevtoolsSplit > .ChatDebugViewDetails {
|
|
2925
|
-
border-left: 0;
|
|
2926
|
-
border-top-left-radius: 0;
|
|
2927
|
-
border-bottom-left-radius: 0;
|
|
2928
|
-
flex: 1;
|
|
2929
|
-
}
|
|
2930
|
-
|
|
2931
|
-
.ChatDebugViewSash {
|
|
2932
|
-
flex: 0 0 var(--ChatDebugViewSashWidth);
|
|
2933
|
-
position: relative;
|
|
2934
|
-
cursor: col-resize;
|
|
2935
|
-
display: flex;
|
|
2936
|
-
justify-content: center;
|
|
2937
|
-
min-height: 0;
|
|
2938
|
-
contain: strict;
|
|
2939
|
-
}
|
|
2940
|
-
|
|
2941
|
-
.ChatDebugViewSashLine {
|
|
2942
|
-
width: 1px;
|
|
2943
|
-
height: 100%;
|
|
2944
|
-
background: var(--vscode-editorWidget-border, #454545);
|
|
2945
|
-
pointer-events: none;
|
|
2946
|
-
contain: strict;
|
|
2947
|
-
}
|
|
2948
|
-
|
|
2949
|
-
.ChatDebugViewSash:hover .ChatDebugViewSashLine {
|
|
2950
|
-
background: var(--vscode-focusBorder, #007fd4);
|
|
2951
|
-
}
|
|
2952
|
-
|
|
2953
|
-
.ChatDebugViewTable {
|
|
2954
|
-
display: flex;
|
|
2955
|
-
flex-direction: column;
|
|
2956
|
-
min-height: 0;
|
|
2957
|
-
flex: 1 1 auto;
|
|
2958
|
-
contain: strict;
|
|
2959
|
-
}
|
|
2960
|
-
|
|
2961
|
-
.ChatDebugViewTimeline {
|
|
2962
|
-
display: flex;
|
|
2963
|
-
flex-direction: column;
|
|
2964
|
-
gap: 6px;
|
|
2965
|
-
padding: 6px ${timelineHorizontalPadding}px 8px;
|
|
2966
|
-
border-bottom: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
2967
|
-
background: color-mix(in srgb, var(--vscode-editorWidget-background, transparent) 82%, var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.12)) 18%);
|
|
2968
|
-
contain: content;
|
|
2969
|
-
}
|
|
2970
|
-
|
|
2971
|
-
.ChatDebugViewTimelineTop {
|
|
2972
|
-
display: flex;
|
|
2973
|
-
align-items: center;
|
|
2974
|
-
contain: content;
|
|
2975
|
-
}
|
|
2976
|
-
|
|
2977
|
-
.ChatDebugViewTimelineSummary {
|
|
2978
|
-
display: flex;
|
|
2979
|
-
align-items: center;
|
|
2980
|
-
font-size: 12px;
|
|
2981
|
-
line-height: 16px;
|
|
2982
|
-
opacity: 0.8;
|
|
2983
|
-
contain: content;
|
|
2984
|
-
}
|
|
2985
|
-
|
|
2986
|
-
.ChatDebugViewTimelineControls {
|
|
2987
|
-
display: flex;
|
|
2988
|
-
align-items: center;
|
|
2989
|
-
gap: 8px;
|
|
2990
|
-
flex-wrap: wrap;
|
|
2991
|
-
contain: content;
|
|
2992
|
-
}
|
|
2993
|
-
|
|
2994
|
-
.ChatDebugViewTimelineBuckets {
|
|
2995
|
-
display: flex;
|
|
2996
|
-
align-items: end;
|
|
2997
|
-
gap: 3px;
|
|
2998
|
-
flex: 1 1 auto;
|
|
2999
|
-
min-height: 52px;
|
|
3000
|
-
pointer-events: none;
|
|
3001
|
-
contain: strict;
|
|
3002
|
-
}
|
|
3003
|
-
|
|
3004
|
-
.ChatDebugViewTimelineInteractive {
|
|
3005
|
-
display: flex;
|
|
3006
|
-
position: relative;
|
|
3007
|
-
min-height: 52px;
|
|
3008
|
-
cursor: crosshair;
|
|
3009
|
-
user-select: none;
|
|
3010
|
-
contain: strict;
|
|
3011
|
-
}
|
|
3012
|
-
|
|
3013
|
-
.ChatDebugViewTimelineSelectionOverlay {
|
|
3014
|
-
position: absolute;
|
|
3015
|
-
inset: 0;
|
|
3016
|
-
pointer-events: none;
|
|
3017
|
-
contain: strict;
|
|
3018
|
-
}
|
|
3019
|
-
|
|
3020
|
-
.ChatDebugViewTimelineSelectionRange {
|
|
3021
|
-
position: absolute;
|
|
3022
|
-
top: 0;
|
|
3023
|
-
bottom: 0;
|
|
3024
|
-
background: color-mix(in srgb, var(--vscode-charts-blue, #75beff) 20%, transparent 80%);
|
|
3025
|
-
border-left: 1px solid color-mix(in srgb, var(--vscode-charts-blue, #75beff) 65%, transparent 35%);
|
|
3026
|
-
border-right: 1px solid color-mix(in srgb, var(--vscode-charts-blue, #75beff) 65%, transparent 35%);
|
|
3027
|
-
contain: strict;
|
|
3028
|
-
}
|
|
3029
|
-
|
|
3030
|
-
.ChatDebugViewTimelineSelectionMarker {
|
|
3031
|
-
position: absolute;
|
|
3032
|
-
top: 0;
|
|
3033
|
-
bottom: 0;
|
|
3034
|
-
width: 1px;
|
|
3035
|
-
margin-left: -0.5px;
|
|
3036
|
-
background: var(--vscode-focusBorder, #007fd4);
|
|
3037
|
-
box-shadow: 0 0 0 1px color-mix(in srgb, var(--vscode-focusBorder, #007fd4) 24%, transparent 76%);
|
|
3038
|
-
contain: strict;
|
|
3039
|
-
}
|
|
3040
|
-
|
|
3041
|
-
.ChatDebugViewTimelineBucket {
|
|
3042
|
-
--ChatDebugViewTimelineBucketBarBackground: color-mix(in srgb, var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.16)) 74%, transparent 26%);
|
|
3043
|
-
--ChatDebugViewTimelineBucketBarBorderColor: transparent;
|
|
3044
|
-
display: flex;
|
|
3045
|
-
align-items: stretch;
|
|
3046
|
-
flex: 1 1 10px;
|
|
3047
|
-
min-width: 10px;
|
|
3048
|
-
min-height: 52px;
|
|
3049
|
-
contain: strict;
|
|
3050
|
-
}
|
|
3051
|
-
|
|
3052
|
-
.ChatDebugViewTimelineBucketSelected {
|
|
3053
|
-
--ChatDebugViewTimelineBucketBarBackground: color-mix(in srgb, var(--vscode-charts-blue, #75beff) 72%, transparent 28%);
|
|
3054
|
-
--ChatDebugViewTimelineBucketBarBorderColor: var(--vscode-focusBorder, #007fd4);
|
|
3055
|
-
}
|
|
3056
|
-
|
|
3057
|
-
.ChatDebugViewTimelinePresetInput {
|
|
3058
|
-
position: absolute;
|
|
3059
|
-
opacity: 0;
|
|
3060
|
-
pointer-events: none;
|
|
3061
|
-
contain: content;
|
|
3062
|
-
}
|
|
3063
|
-
|
|
3064
|
-
.ChatDebugViewTimelineBucketBar {
|
|
3065
|
-
display: flex;
|
|
3066
|
-
flex-direction: column;
|
|
3067
|
-
justify-content: flex-end;
|
|
3068
|
-
gap: 2px;
|
|
3069
|
-
padding: 6px 1px 2px;
|
|
3070
|
-
border: 1px solid transparent;
|
|
3071
|
-
border-radius: 2px;
|
|
3072
|
-
width: 100%;
|
|
3073
|
-
background: var(--ChatDebugViewTimelineBucketBarBackground);
|
|
3074
|
-
border-color: var(--ChatDebugViewTimelineBucketBarBorderColor);
|
|
3075
|
-
contain: strict;
|
|
3076
|
-
}
|
|
3077
|
-
|
|
3078
|
-
.ChatDebugViewTimelineBucketBarSelected {
|
|
3079
|
-
background: color-mix(in srgb, var(--vscode-charts-blue, #75beff) 72%, transparent 28%);
|
|
3080
|
-
border-color: var(--vscode-focusBorder, #007fd4);
|
|
3081
|
-
}
|
|
3082
|
-
|
|
3083
|
-
.ChatDebugViewTimelineBucketUnit {
|
|
3084
|
-
width: 100%;
|
|
3085
|
-
height: 4px;
|
|
3086
|
-
border-radius: 999px;
|
|
3087
|
-
background: var(--vscode-charts-blue, #75beff);
|
|
3088
|
-
contain: strict;
|
|
3089
|
-
}
|
|
3090
|
-
|
|
3091
|
-
.ChatDebugViewTimelineBucketUnitEmpty {
|
|
3092
|
-
opacity: 0.35;
|
|
3093
|
-
background: var(--vscode-editorWidget-border, #454545);
|
|
3094
|
-
}
|
|
3095
|
-
|
|
3096
|
-
.ChatDebugViewTableHeaderRow,
|
|
3097
|
-
.ChatDebugViewEventRow {
|
|
3098
|
-
display: flex;
|
|
3099
|
-
align-items: center;
|
|
3100
|
-
gap: 8px;
|
|
3101
|
-
contain: content;
|
|
3102
|
-
}
|
|
3103
|
-
|
|
3104
|
-
.ChatDebugViewTableHeader {
|
|
3105
|
-
padding: 3px 8px;
|
|
3106
|
-
border-bottom: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
3107
|
-
background: var(--vscode-editorWidget-background, transparent);
|
|
3108
|
-
position: sticky;
|
|
3109
|
-
top: 0;
|
|
3110
|
-
z-index: 1;
|
|
3111
|
-
contain: content;
|
|
3112
|
-
}
|
|
3113
|
-
|
|
3114
|
-
.ChatDebugViewHeaderCell {
|
|
3115
|
-
display: flex;
|
|
3116
|
-
align-items: center;
|
|
3117
|
-
overflow: hidden;
|
|
3118
|
-
text-overflow: ellipsis;
|
|
3119
|
-
white-space: nowrap;
|
|
3120
|
-
min-width: 0;
|
|
3121
|
-
font-size: 11px;
|
|
3122
|
-
letter-spacing: 0.04em;
|
|
3123
|
-
opacity: 0.8;
|
|
3124
|
-
contain: content;
|
|
3125
|
-
}
|
|
3126
|
-
|
|
3127
|
-
.ChatDebugViewTableHeaderRow > .ChatDebugViewHeaderCell:nth-child(1) {
|
|
3128
|
-
flex: 1 1 140px;
|
|
3129
|
-
min-width: 0;
|
|
3130
|
-
}
|
|
3131
|
-
|
|
3132
|
-
.ChatDebugViewTableHeaderRow > .ChatDebugViewHeaderCell:nth-child(2) {
|
|
3133
|
-
flex: 0 0 90px;
|
|
3134
|
-
justify-content: flex-end;
|
|
3135
|
-
}
|
|
3136
|
-
|
|
3137
|
-
.ChatDebugViewTableHeaderRow > .ChatDebugViewHeaderCell:nth-child(3) {
|
|
3138
|
-
flex: 0 0 96px;
|
|
3139
|
-
justify-content: flex-end;
|
|
3140
|
-
}
|
|
3141
|
-
|
|
3142
|
-
.ChatDebugViewTableBody {
|
|
3143
|
-
display: flex;
|
|
3144
|
-
flex-direction: column;
|
|
3145
|
-
overflow: auto;
|
|
3146
|
-
min-height: 0;
|
|
3147
|
-
flex: 1 1 auto;
|
|
3148
|
-
contain: strict;
|
|
3149
|
-
}
|
|
3150
|
-
|
|
3151
|
-
.ChatDebugViewEventRowLabel {
|
|
3152
|
-
display: block;
|
|
3153
|
-
contain: content;
|
|
3154
|
-
}
|
|
3155
|
-
|
|
3156
|
-
.ChatDebugViewEventRowLabelSelected .ChatDebugViewEventRow,
|
|
3157
|
-
.ChatDebugViewEventRowSelected {
|
|
3158
|
-
background: var(--vscode-list-activeSelectionBackground, rgba(14, 99, 156, 0.35));
|
|
3159
|
-
color: var(--vscode-list-activeSelectionForeground, inherit);
|
|
3160
|
-
}
|
|
3161
|
-
|
|
3162
|
-
.ChatDebugViewEventRowInput {
|
|
3163
|
-
position: absolute;
|
|
3164
|
-
opacity: 0;
|
|
3165
|
-
pointer-events: none;
|
|
3166
|
-
contain: content;
|
|
3167
|
-
}
|
|
3168
|
-
|
|
3169
|
-
.ChatDebugViewEventRow {
|
|
3170
|
-
padding: 2px 8px;
|
|
3171
|
-
background: color-mix(in srgb, var(--vscode-editorWidget-background, transparent) 92%, var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.31)) 8%);
|
|
3172
|
-
cursor: default;
|
|
3173
|
-
}
|
|
3174
|
-
|
|
3175
|
-
.ChatDebugViewTableBody > .ChatDebugViewEventRow:nth-child(even) {
|
|
3176
|
-
background: color-mix(in srgb, var(--vscode-editorWidget-background, transparent) 84%, var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.31)) 16%);
|
|
3177
|
-
}
|
|
3178
|
-
|
|
3179
|
-
.ChatDebugViewEventRow:hover {
|
|
3180
|
-
background: var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.31));
|
|
3181
|
-
color: var(--vscode-list-hoverForeground, inherit);
|
|
3182
|
-
}
|
|
3183
|
-
|
|
3184
|
-
.ChatDebugViewCell {
|
|
3185
|
-
display: flex;
|
|
3186
|
-
align-items: center;
|
|
3187
|
-
overflow: hidden;
|
|
3188
|
-
text-overflow: ellipsis;
|
|
3189
|
-
white-space: nowrap;
|
|
3190
|
-
min-width: 0;
|
|
3191
|
-
pointer-events: none;
|
|
3192
|
-
contain: content;
|
|
3193
|
-
}
|
|
3194
|
-
|
|
3195
|
-
.ChatDebugViewCellType {
|
|
3196
|
-
flex: 1 1 140px;
|
|
3197
|
-
min-width: 0;
|
|
3198
|
-
}
|
|
3199
|
-
|
|
3200
|
-
.ChatDebugViewCellTime {
|
|
3201
|
-
flex: 1 1 180px;
|
|
3202
|
-
min-width: 0;
|
|
3203
|
-
}
|
|
3204
|
-
|
|
3205
|
-
.ChatDebugViewCellDuration {
|
|
3206
|
-
flex: 0 0 90px;
|
|
3207
|
-
justify-content: flex-end;
|
|
3208
|
-
text-align: right;
|
|
3209
|
-
}
|
|
3210
|
-
|
|
3211
|
-
.ChatDebugViewCellStatus {
|
|
3212
|
-
flex: 0 0 64px;
|
|
3213
|
-
justify-content: flex-end;
|
|
3214
|
-
text-align: right;
|
|
3215
|
-
}
|
|
3216
|
-
|
|
3217
|
-
.ChatDebugViewCellStatusError {
|
|
3218
|
-
color: var(--vscode-errorForeground, #f14c4c);
|
|
3219
|
-
}
|
|
3220
|
-
|
|
3221
|
-
.ChatDebugViewDetails {
|
|
3222
|
-
border: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
3223
|
-
border-radius: 6px;
|
|
3224
|
-
overflow: hidden;
|
|
3225
|
-
min-width: 0;
|
|
3226
|
-
min-height: 0;
|
|
3227
|
-
display: flex;
|
|
3228
|
-
flex-direction: column;
|
|
3229
|
-
contain: strict;
|
|
3230
|
-
}
|
|
3231
|
-
|
|
3232
|
-
.ChatDebugViewDetailsTop {
|
|
3233
|
-
display: flex;
|
|
3234
|
-
align-items: stretch;
|
|
3235
|
-
justify-content: flex-start;
|
|
3236
|
-
gap: 8px;
|
|
3237
|
-
padding: 0 8px;
|
|
3238
|
-
border-bottom: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
3239
|
-
background: color-mix(in srgb, var(--vscode-editorWidget-background, transparent) 72%, var(--vscode-list-hoverBackground, rgba(90, 93, 94, 0.18)) 28%);
|
|
3240
|
-
contain: content;
|
|
3241
|
-
}
|
|
3242
|
-
|
|
3243
|
-
.ChatDebugViewDetailsClose {
|
|
3244
|
-
width: 18px;
|
|
3245
|
-
height: 18px;
|
|
3246
|
-
appearance: none;
|
|
3247
|
-
border: none;
|
|
3248
|
-
border-radius: 4px;
|
|
3249
|
-
cursor: pointer;
|
|
3250
|
-
position: relative;
|
|
3251
|
-
color: var(--vscode-foreground, #cccccc);
|
|
3252
|
-
background: transparent;
|
|
3253
|
-
align-self: center;
|
|
3254
|
-
flex: 0 0 auto;
|
|
3255
|
-
contain: strict;
|
|
3256
|
-
}
|
|
3257
|
-
|
|
3258
|
-
.ChatDebugViewDetailsClose:hover {
|
|
3259
|
-
background: var(--vscode-toolbar-hoverBackground, rgba(90, 93, 94, 0.31));
|
|
3260
|
-
}
|
|
3261
|
-
|
|
3262
|
-
.ChatDebugViewDetailsClose::before,
|
|
3263
|
-
.ChatDebugViewDetailsClose::after {
|
|
3264
|
-
content: '';
|
|
3265
|
-
position: absolute;
|
|
3266
|
-
left: 50%;
|
|
3267
|
-
top: 50%;
|
|
3268
|
-
width: 10px;
|
|
3269
|
-
height: 1px;
|
|
3270
|
-
background: currentColor;
|
|
3271
|
-
}
|
|
3272
|
-
|
|
3273
|
-
.ChatDebugViewDetailsClose::before {
|
|
3274
|
-
transform: translate(-50%, -50%) rotate(45deg);
|
|
3275
|
-
}
|
|
3276
|
-
|
|
3277
|
-
.ChatDebugViewDetailsClose::after {
|
|
3278
|
-
transform: translate(-50%, -50%) rotate(-45deg);
|
|
3279
|
-
}
|
|
3280
|
-
|
|
3281
|
-
.ChatDebugViewDetailsBody {
|
|
3282
|
-
display: flex;
|
|
3283
|
-
flex-direction: column;
|
|
3284
|
-
overflow: hidden;
|
|
3285
|
-
padding: 0;
|
|
3286
|
-
flex: 1 1 auto;
|
|
3287
|
-
min-height: 0;
|
|
3288
|
-
align-items: stretch;
|
|
3289
|
-
contain: strict;
|
|
3290
|
-
}
|
|
3291
|
-
|
|
3292
|
-
.ChatDebugViewDetailsTabs {
|
|
3293
|
-
display: flex;
|
|
3294
|
-
align-items: center;
|
|
3295
|
-
flex: 1 1 auto;
|
|
3296
|
-
gap: 2px;
|
|
3297
|
-
min-width: 0;
|
|
3298
|
-
padding: 0;
|
|
3299
|
-
overflow-x: auto;
|
|
3300
|
-
contain: content;
|
|
3301
|
-
}
|
|
3302
|
-
|
|
3303
|
-
.ChatDebugViewDetailsTab {
|
|
3304
|
-
display: flex;
|
|
3305
|
-
align-items: center;
|
|
3306
|
-
justify-content: center;
|
|
3307
|
-
min-height: 32px;
|
|
3308
|
-
padding: 0 10px;
|
|
3309
|
-
appearance: none;
|
|
3310
|
-
background: transparent;
|
|
3311
|
-
border: 0;
|
|
3312
|
-
border-bottom: 2px solid transparent;
|
|
3313
|
-
color: var(--vscode-descriptionForeground, var(--vscode-foreground, #cccccc));
|
|
3314
|
-
cursor: pointer;
|
|
3315
|
-
white-space: nowrap;
|
|
3316
|
-
contain: content;
|
|
3317
|
-
}
|
|
3318
|
-
|
|
3319
|
-
.ChatDebugViewDetailsTab:hover {
|
|
3320
|
-
color: var(--vscode-foreground, #cccccc);
|
|
3321
|
-
}
|
|
3322
|
-
|
|
3323
|
-
.ChatDebugViewDetailsTabSelected {
|
|
3324
|
-
border-bottom-color: var(--vscode-focusBorder, #007fd4);
|
|
3325
|
-
color: var(--vscode-focusBorder, #007fd4);
|
|
3326
|
-
}
|
|
3327
|
-
|
|
3328
|
-
.ChatDebugViewDetailsPanel {
|
|
3329
|
-
display: flex;
|
|
3330
|
-
flex-direction: column;
|
|
3331
|
-
overflow: auto;
|
|
3332
|
-
padding: 8px;
|
|
3333
|
-
flex: 1 1 auto;
|
|
3334
|
-
min-height: 0;
|
|
3335
|
-
align-items: flex-start;
|
|
3336
|
-
contain: strict;
|
|
3337
|
-
}
|
|
3338
|
-
|
|
3339
|
-
.ChatDebugViewEvents::-webkit-scrollbar {
|
|
3340
|
-
width: 10px;
|
|
3341
|
-
height: 10px;
|
|
3342
|
-
}
|
|
3343
|
-
|
|
3344
|
-
.ChatDebugViewEvents::-webkit-scrollbar-track {
|
|
3345
|
-
background: transparent;
|
|
3346
|
-
}
|
|
3347
|
-
|
|
3348
|
-
.ChatDebugViewEvents::-webkit-scrollbar-thumb {
|
|
3349
|
-
background: var(--vscode-scrollbarSlider-background, rgba(121, 121, 121, 0.4));
|
|
3350
|
-
border-radius: 999px;
|
|
3351
|
-
border: 2px solid transparent;
|
|
3352
|
-
background-clip: content-box;
|
|
3353
|
-
}
|
|
3354
|
-
|
|
3355
|
-
.ChatDebugViewEvents::-webkit-scrollbar-thumb:hover {
|
|
3356
|
-
background: var(--vscode-scrollbarSlider-hoverBackground, rgba(100, 100, 100, 0.7));
|
|
3357
|
-
}
|
|
3358
|
-
|
|
3359
|
-
.ChatDebugViewEvents::-webkit-scrollbar-thumb:active {
|
|
3360
|
-
background: var(--vscode-scrollbarSlider-activeBackground, rgba(191, 191, 191, 0.4));
|
|
3361
|
-
}
|
|
3362
|
-
|
|
3363
|
-
.ChatDebugViewEvent {
|
|
3364
|
-
display: flex;
|
|
3365
|
-
flex-direction: column;
|
|
3366
|
-
width: max-content;
|
|
3367
|
-
min-width: 100%;
|
|
3368
|
-
margin: 0;
|
|
3369
|
-
padding: 8px;
|
|
3370
|
-
border: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
3371
|
-
border-radius: 6px;
|
|
3372
|
-
margin-bottom: 8px;
|
|
3373
|
-
white-space: nowrap;
|
|
3374
|
-
font-family: var(--vscode-editor-font-family, monospace);
|
|
3375
|
-
font-size: 12px;
|
|
3376
|
-
user-select: text;
|
|
3377
|
-
contain: content;
|
|
3378
|
-
}
|
|
3379
|
-
|
|
3380
|
-
.row {
|
|
3381
|
-
display: flex;
|
|
3382
|
-
align-items: baseline;
|
|
3383
|
-
gap: 12px;
|
|
3384
|
-
min-width: 100%;
|
|
3385
|
-
width: max-content;
|
|
3386
|
-
white-space: nowrap;
|
|
3387
|
-
contain: strict;
|
|
3388
|
-
height: 20px;
|
|
3389
|
-
}
|
|
3390
|
-
|
|
3391
|
-
.ChatDebugViewEventLineNumber {
|
|
3392
|
-
display: flex;
|
|
3393
|
-
justify-content: flex-end;
|
|
3394
|
-
flex: 0 0 3ch;
|
|
3395
|
-
opacity: 0.6;
|
|
3396
|
-
user-select: none;
|
|
3397
|
-
contain: content;
|
|
3398
|
-
}
|
|
3399
|
-
|
|
3400
|
-
.ChatDebugViewEventLineContent {
|
|
3401
|
-
display: flex;
|
|
3402
|
-
white-space: pre;
|
|
3403
|
-
contain: content;
|
|
3404
|
-
}
|
|
2486
|
+
timelineStartSeconds: value
|
|
2487
|
+
};
|
|
2488
|
+
return withPreservedSelection$1(state, nextState);
|
|
2489
|
+
};
|
|
2490
|
+
const handleTimelineEndSeconds = (state, value) => {
|
|
2491
|
+
const nextState = {
|
|
2492
|
+
...state,
|
|
2493
|
+
timelineEndSeconds: value
|
|
2494
|
+
};
|
|
2495
|
+
return withPreservedSelection$1(state, nextState);
|
|
2496
|
+
};
|
|
2497
|
+
const handleTimelineRangePreset = (state, value) => {
|
|
2498
|
+
const nextState = {
|
|
2499
|
+
...state,
|
|
2500
|
+
...parseTimelineRangePreset(value)
|
|
2501
|
+
};
|
|
2502
|
+
return withPreservedSelection$1(state, nextState);
|
|
2503
|
+
};
|
|
3405
2504
|
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
}
|
|
2505
|
+
const handleTimelineDoubleClick = state => {
|
|
2506
|
+
const nextState = handleTimelineRangePreset(state, '');
|
|
2507
|
+
return clearTimelineSelectionState(nextState);
|
|
2508
|
+
};
|
|
3411
2509
|
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
2510
|
+
const getTimelineEvents = state => {
|
|
2511
|
+
const {
|
|
2512
|
+
eventCategoryFilter,
|
|
2513
|
+
events,
|
|
2514
|
+
filterValue,
|
|
2515
|
+
showEventStreamFinishedEvents,
|
|
2516
|
+
showInputEvents,
|
|
2517
|
+
showResponsePartEvents
|
|
2518
|
+
} = state;
|
|
2519
|
+
return getFilteredEvents(events, filterValue, eventCategoryFilter, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents);
|
|
2520
|
+
};
|
|
3419
2521
|
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
border-bottom: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
3427
|
-
contain: content;
|
|
3428
|
-
}
|
|
2522
|
+
const getTimelineLeft = state => {
|
|
2523
|
+
return state.x + viewPadding + timelineHorizontalPadding;
|
|
2524
|
+
};
|
|
2525
|
+
const getTimelineWidth = state => {
|
|
2526
|
+
return Math.max(0, getMainWidth(state.width) - timelineHorizontalPadding * 2);
|
|
2527
|
+
};
|
|
3429
2528
|
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
2529
|
+
const trailingZeroFractionRegex = /\.0+$/;
|
|
2530
|
+
const trailingFractionZeroRegex = /(\.\d*?)0+$/;
|
|
2531
|
+
const formatTimelinePresetValue = value => {
|
|
2532
|
+
return value.toFixed(3).replace(trailingZeroFractionRegex, '').replace(trailingFractionZeroRegex, '$1');
|
|
2533
|
+
};
|
|
3433
2534
|
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
}
|
|
2535
|
+
const getTimelineSecondsFromClientX = (events, eventX, timelineLeft, timelineWidth) => {
|
|
2536
|
+
if (timelineWidth <= 0) {
|
|
2537
|
+
return undefined;
|
|
2538
|
+
}
|
|
2539
|
+
const durationSeconds = getTimelineDurationSeconds(events);
|
|
2540
|
+
const relativeX = Math.min(Math.max(eventX - timelineLeft, 0), timelineWidth);
|
|
2541
|
+
const ratio = relativeX / timelineWidth;
|
|
2542
|
+
return formatTimelinePresetValue(durationSeconds * ratio);
|
|
2543
|
+
};
|
|
3438
2544
|
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
2545
|
+
const handleTimelinePointerDown = (state, eventX) => {
|
|
2546
|
+
const timelineEvents = getTimelineEvents(state);
|
|
2547
|
+
const timelineLeft = getTimelineLeft(state);
|
|
2548
|
+
const timelineWidth = getTimelineWidth(state);
|
|
2549
|
+
const clientX = state.x + eventX;
|
|
2550
|
+
const seconds = getTimelineSecondsFromClientX(timelineEvents, clientX, timelineLeft, timelineWidth);
|
|
2551
|
+
if (seconds === undefined) {
|
|
2552
|
+
return state;
|
|
2553
|
+
}
|
|
2554
|
+
return {
|
|
2555
|
+
...state,
|
|
2556
|
+
timelineSelectionActive: true,
|
|
2557
|
+
timelineSelectionAnchorSeconds: seconds,
|
|
2558
|
+
timelineSelectionFocusSeconds: seconds
|
|
2559
|
+
};
|
|
2560
|
+
};
|
|
3444
2561
|
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
2562
|
+
const handleTimelinePointerMove = (state, eventX) => {
|
|
2563
|
+
if (!state.timelineSelectionActive) {
|
|
2564
|
+
return state;
|
|
2565
|
+
}
|
|
2566
|
+
const timelineEvents = getTimelineEvents(state);
|
|
2567
|
+
const timelineLeft = getTimelineLeft(state);
|
|
2568
|
+
const timelineWidth = getTimelineWidth(state);
|
|
2569
|
+
const clientX = state.x + eventX;
|
|
2570
|
+
const seconds = getTimelineSecondsFromClientX(timelineEvents, clientX, timelineLeft, timelineWidth);
|
|
2571
|
+
if (seconds === undefined) {
|
|
2572
|
+
return state;
|
|
2573
|
+
}
|
|
2574
|
+
return {
|
|
2575
|
+
...state,
|
|
2576
|
+
timelineSelectionFocusSeconds: seconds
|
|
2577
|
+
};
|
|
2578
|
+
};
|
|
3451
2579
|
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
2580
|
+
const handleTimelinePointerUp = (state, eventX) => {
|
|
2581
|
+
if (!state.timelineSelectionActive) {
|
|
2582
|
+
return state;
|
|
2583
|
+
}
|
|
2584
|
+
const timelineEvents = getTimelineEvents(state);
|
|
2585
|
+
const timelineLeft = getTimelineLeft(state);
|
|
2586
|
+
const timelineWidth = getTimelineWidth(state);
|
|
2587
|
+
const clientX = state.x + eventX;
|
|
2588
|
+
const focusSeconds = getTimelineSecondsFromClientX(timelineEvents, clientX, timelineLeft, timelineWidth);
|
|
2589
|
+
if (focusSeconds === undefined) {
|
|
2590
|
+
return clearTimelineSelectionState(state);
|
|
2591
|
+
}
|
|
2592
|
+
const anchor = Number.parseFloat(state.timelineSelectionAnchorSeconds);
|
|
2593
|
+
const focus = Number.parseFloat(focusSeconds);
|
|
2594
|
+
const startSeconds = formatTimelinePresetValue(Math.min(anchor, focus));
|
|
2595
|
+
const endSeconds = formatTimelinePresetValue(Math.max(anchor, focus));
|
|
2596
|
+
const nextState = handleTimelineRangePreset(state, `${startSeconds}:${endSeconds}`);
|
|
2597
|
+
return clearTimelineSelectionState(nextState);
|
|
2598
|
+
};
|
|
3458
2599
|
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
2600
|
+
const handleUseDevtoolsLayout = (state, checked) => {
|
|
2601
|
+
const useDevtoolsLayout = getBoolean(checked);
|
|
2602
|
+
const selectedEventIndex = useDevtoolsLayout ? getSelectedEventIndex$1(state) : null;
|
|
2603
|
+
return {
|
|
2604
|
+
...state,
|
|
2605
|
+
selectedEvent: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEvent : null,
|
|
2606
|
+
selectedEventId: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEventId : null,
|
|
2607
|
+
selectedEventIndex,
|
|
2608
|
+
useDevtoolsLayout
|
|
2609
|
+
};
|
|
2610
|
+
};
|
|
3462
2611
|
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
2612
|
+
const handleShowEventStreamFinishedEvents = (state, checked) => {
|
|
2613
|
+
const nextState = {
|
|
2614
|
+
...state,
|
|
2615
|
+
showEventStreamFinishedEvents: getBoolean(checked)
|
|
2616
|
+
};
|
|
2617
|
+
return withPreservedSelection$1(state, nextState);
|
|
2618
|
+
};
|
|
2619
|
+
const handleShowInputEvents = (state, checked) => {
|
|
2620
|
+
const nextState = {
|
|
2621
|
+
...state,
|
|
2622
|
+
showInputEvents: getBoolean(checked)
|
|
2623
|
+
};
|
|
2624
|
+
return withPreservedSelection$1(state, nextState);
|
|
2625
|
+
};
|
|
2626
|
+
const handleShowResponsePartEvents = (state, checked) => {
|
|
2627
|
+
const nextState = {
|
|
2628
|
+
...state,
|
|
2629
|
+
showResponsePartEvents: getBoolean(checked)
|
|
2630
|
+
};
|
|
2631
|
+
return withPreservedSelection$1(state, nextState);
|
|
2632
|
+
};
|
|
3466
2633
|
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
}
|
|
2634
|
+
const loadContent = async state => {
|
|
2635
|
+
return loadEventsFromUri(state);
|
|
2636
|
+
};
|
|
3470
2637
|
|
|
3471
|
-
|
|
3472
|
-
|
|
2638
|
+
const getCss = state => {
|
|
2639
|
+
const tableWidth = clampTableWidth(state.width, state.tableWidth);
|
|
2640
|
+
const detailsWidth = getDetailsWidth(state.width, state.tableWidth);
|
|
2641
|
+
return `
|
|
2642
|
+
.ChatDebugView {
|
|
2643
|
+
--ChatDebugViewDetailsWidth: ${detailsWidth}px;
|
|
2644
|
+
--ChatDebugViewSashWidth: ${sashWidth}px;
|
|
2645
|
+
--ChatDebugViewTableWidth: ${tableWidth}px;
|
|
2646
|
+
padding: ${viewPadding}px;
|
|
3473
2647
|
}
|
|
3474
2648
|
|
|
3475
|
-
.TokenBoolean {
|
|
3476
|
-
color: var(--vscode-debugTokenExpression-boolean, var(--vscode-charts-yellow, #dcdcaa));
|
|
3477
|
-
}
|
|
3478
2649
|
|
|
3479
|
-
.
|
|
3480
|
-
|
|
3481
|
-
flex-direction:column;
|
|
3482
|
-
margin:0;
|
|
3483
|
-
padding:0;
|
|
3484
|
-
padding-left:10px;
|
|
3485
|
-
contain: content;
|
|
2650
|
+
.ChatDebugViewDetails {
|
|
2651
|
+
contain: strict;
|
|
3486
2652
|
}
|
|
3487
2653
|
|
|
3488
|
-
.
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
padding:0;
|
|
3492
|
-
contain: content;
|
|
2654
|
+
.ChatDebugViewDetailsTop {
|
|
2655
|
+
height: 33px;
|
|
2656
|
+
contain: strict;
|
|
3493
2657
|
}
|
|
3494
2658
|
|
|
3495
|
-
.
|
|
3496
|
-
|
|
3497
|
-
flex-direction:column;
|
|
3498
|
-
margin:0;
|
|
3499
|
-
padding:0;
|
|
3500
|
-
contain: content;
|
|
2659
|
+
.ChatDebugViewEvent {
|
|
2660
|
+
contain: content
|
|
3501
2661
|
}
|
|
3502
2662
|
`;
|
|
3503
2663
|
};
|
|
@@ -3806,9 +2966,8 @@ const diffTree = (oldNodes, newNodes) => {
|
|
|
3806
2966
|
const ChatDebugView = 'ChatDebugView';
|
|
3807
2967
|
const ChatDebugViewDevtools = 'ChatDebugView--devtools';
|
|
3808
2968
|
const ChatDebugViewDetails = 'ChatDebugViewDetails';
|
|
3809
|
-
const
|
|
2969
|
+
const ChatDebugViewDetailsBottom = 'ChatDebugViewDetailsBottom';
|
|
3810
2970
|
const ChatDebugViewDetailsClose = 'ChatDebugViewDetailsClose';
|
|
3811
|
-
const ChatDebugViewDetailsPanel = 'ChatDebugViewDetailsPanel';
|
|
3812
2971
|
const ChatDebugViewDetailsTab = 'ChatDebugViewDetailsTab';
|
|
3813
2972
|
const ChatDebugViewDetailsTabSelected = 'ChatDebugViewDetailsTabSelected';
|
|
3814
2973
|
const ChatDebugViewDetailsTabs = 'ChatDebugViewDetailsTabs';
|
|
@@ -3827,6 +2986,7 @@ const ChatDebugViewEventsFullWidth = 'ChatDebugViewEventsFullWidth';
|
|
|
3827
2986
|
const ChatDebugViewFilterInput = 'ChatDebugViewFilterInput';
|
|
3828
2987
|
const ChatDebugViewFilterInputDevtools = 'ChatDebugViewFilterInput--devtools';
|
|
3829
2988
|
const ChatDebugViewHeaderCell = 'ChatDebugViewHeaderCell';
|
|
2989
|
+
const ChatDebugViewRefreshButton = 'ChatDebugViewRefreshButton';
|
|
3830
2990
|
const ChatDebugViewQuickFilterInput = 'ChatDebugViewQuickFilterInput';
|
|
3831
2991
|
const ChatDebugViewQuickFilterPill = 'ChatDebugViewQuickFilterPill';
|
|
3832
2992
|
const ChatDebugViewQuickFilterPillSelected = 'ChatDebugViewQuickFilterPillSelected';
|
|
@@ -3846,7 +3006,6 @@ const ChatDebugViewTimelineBucketUnit = 'ChatDebugViewTimelineBucketUnit';
|
|
|
3846
3006
|
const ChatDebugViewTimelineBucketUnitEmpty = 'ChatDebugViewTimelineBucketUnitEmpty';
|
|
3847
3007
|
const ChatDebugViewTimelineBuckets = 'ChatDebugViewTimelineBuckets';
|
|
3848
3008
|
const ChatDebugViewTimelineInteractive = 'ChatDebugViewTimelineInteractive';
|
|
3849
|
-
const ChatDebugViewTimelinePresetInput = 'ChatDebugViewTimelinePresetInput';
|
|
3850
3009
|
const ChatDebugViewTimelineSelectionMarker = 'ChatDebugViewTimelineSelectionMarker';
|
|
3851
3010
|
const ChatDebugViewTimelineSelectionMarkerEnd = 'ChatDebugViewTimelineSelectionMarkerEnd';
|
|
3852
3011
|
const ChatDebugViewTimelineSelectionMarkerStart = 'ChatDebugViewTimelineSelectionMarkerStart';
|
|
@@ -3867,11 +3026,11 @@ const ChatDebugViewCellStatusError = 'ChatDebugViewCellStatusError';
|
|
|
3867
3026
|
const ChatDebugViewCellType = 'ChatDebugViewCellType';
|
|
3868
3027
|
const InputBox = 'InputBox';
|
|
3869
3028
|
const Row = 'row';
|
|
3870
|
-
const TokenBoolean = 'TokenBoolean';
|
|
3871
|
-
const TokenKey = 'TokenKey';
|
|
3872
|
-
const TokenNumeric = 'TokenNumeric';
|
|
3873
|
-
const TokenString = 'TokenString';
|
|
3874
|
-
const TokenText = 'TokenText';
|
|
3029
|
+
const TokenBoolean = 'Token TokenBoolean';
|
|
3030
|
+
const TokenKey = 'Token TokenKey';
|
|
3031
|
+
const TokenNumeric = 'Token TokenNumeric';
|
|
3032
|
+
const TokenString = 'Token TokenString';
|
|
3033
|
+
const TokenText = 'Token TokenText';
|
|
3875
3034
|
const joinClassNames = (...classNames) => {
|
|
3876
3035
|
return classNames.filter(Boolean).join(' ');
|
|
3877
3036
|
};
|
|
@@ -3905,11 +3064,24 @@ const HandleTimelineDoubleClick = 17;
|
|
|
3905
3064
|
const HandleTableKeyDown = 18;
|
|
3906
3065
|
const HandleTimelineRangePreset = 19;
|
|
3907
3066
|
const HandleCloseDetails = 20;
|
|
3067
|
+
const HandleClickRefresh = 21;
|
|
3908
3068
|
|
|
3069
|
+
const getRefreshButtonDom = () => {
|
|
3070
|
+
return [{
|
|
3071
|
+
'aria-label': 'Refresh events',
|
|
3072
|
+
childCount: 1,
|
|
3073
|
+
className: ChatDebugViewRefreshButton,
|
|
3074
|
+
name: Refresh,
|
|
3075
|
+
onClick: HandleClickRefresh,
|
|
3076
|
+
type: Button$1,
|
|
3077
|
+
value: Refresh
|
|
3078
|
+
}, text('Refresh')];
|
|
3079
|
+
};
|
|
3909
3080
|
const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) => {
|
|
3081
|
+
const refreshButtonDom = getRefreshButtonDom();
|
|
3910
3082
|
if (useDevtoolsLayout) {
|
|
3911
3083
|
return [{
|
|
3912
|
-
childCount:
|
|
3084
|
+
childCount: 2 + (quickFilterNodes.length > 0 ? 1 : 0),
|
|
3913
3085
|
className: joinClassNames(ChatDebugViewTop, ChatDebugViewTopDevtools),
|
|
3914
3086
|
onContextMenu: HandleHeaderContextMenu,
|
|
3915
3087
|
type: Search
|
|
@@ -3923,10 +3095,10 @@ const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) =>
|
|
|
3923
3095
|
placeholder: 'Filter events',
|
|
3924
3096
|
type: Input,
|
|
3925
3097
|
value: filterValue
|
|
3926
|
-
}, ...quickFilterNodes];
|
|
3098
|
+
}, ...quickFilterNodes, ...refreshButtonDom];
|
|
3927
3099
|
}
|
|
3928
3100
|
return [{
|
|
3929
|
-
childCount:
|
|
3101
|
+
childCount: 2,
|
|
3930
3102
|
className: ChatDebugViewTop,
|
|
3931
3103
|
onContextMenu: HandleHeaderContextMenu,
|
|
3932
3104
|
type: Search
|
|
@@ -3940,7 +3112,7 @@ const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) =>
|
|
|
3940
3112
|
placeholder: 'Filter events',
|
|
3941
3113
|
type: Input,
|
|
3942
3114
|
value: filterValue
|
|
3943
|
-
}];
|
|
3115
|
+
}, ...refreshButtonDom];
|
|
3944
3116
|
};
|
|
3945
3117
|
|
|
3946
3118
|
const getDurationText = event => {
|
|
@@ -4036,7 +3208,7 @@ const getTabNodes = selectedDetailTab => {
|
|
|
4036
3208
|
onClick: HandleDetailTab,
|
|
4037
3209
|
role: 'tab',
|
|
4038
3210
|
tabIndex: isSelected ? 0 : -1,
|
|
4039
|
-
type: Button,
|
|
3211
|
+
type: Button$1,
|
|
4040
3212
|
value: detailTab
|
|
4041
3213
|
}, text(getDetailTabLabel(detailTab))];
|
|
4042
3214
|
});
|
|
@@ -4061,7 +3233,7 @@ const getDetailsDom = (previewEventNodes, responseEventNodes = previewEventNodes
|
|
|
4061
3233
|
name: CloseDetails,
|
|
4062
3234
|
onChange: HandleCloseDetails,
|
|
4063
3235
|
onClick: HandleCloseDetails,
|
|
4064
|
-
type: Button,
|
|
3236
|
+
type: Button$1,
|
|
4065
3237
|
value: 'close'
|
|
4066
3238
|
}, {
|
|
4067
3239
|
'aria-label': 'Detail sections',
|
|
@@ -4070,14 +3242,9 @@ const getDetailsDom = (previewEventNodes, responseEventNodes = previewEventNodes
|
|
|
4070
3242
|
role: 'tablist',
|
|
4071
3243
|
type: Div
|
|
4072
3244
|
}, ...getTabNodes(selectedDetailTab), {
|
|
4073
|
-
childCount: 1,
|
|
4074
|
-
className: ChatDebugViewDetailsBody,
|
|
4075
|
-
role: 'document',
|
|
4076
|
-
type: Div
|
|
4077
|
-
}, {
|
|
4078
3245
|
'aria-labelledby': getTabId(selectedDetailTab),
|
|
4079
3246
|
childCount: 1,
|
|
4080
|
-
className:
|
|
3247
|
+
className: ChatDebugViewDetailsBottom,
|
|
4081
3248
|
id: getPanelId(selectedDetailTab),
|
|
4082
3249
|
onContextMenu: HandleDetailsContextMenu,
|
|
4083
3250
|
role: 'tabpanel',
|
|
@@ -4151,6 +3318,9 @@ const hasErrorStatus = event => {
|
|
|
4151
3318
|
if (isErrorStatusCode(result.status)) {
|
|
4152
3319
|
return true;
|
|
4153
3320
|
}
|
|
3321
|
+
if (isToolEvent(event) && 'error' in result && result.error !== undefined) {
|
|
3322
|
+
return true;
|
|
3323
|
+
}
|
|
4154
3324
|
if (typeof result.error === 'string' || typeof result.errorMessage === 'string' || typeof result.exception === 'string') {
|
|
4155
3325
|
return true;
|
|
4156
3326
|
}
|
|
@@ -4196,28 +3366,53 @@ const getEmptyStateDom = emptyMessage => {
|
|
|
4196
3366
|
}, text(emptyMessage)];
|
|
4197
3367
|
};
|
|
4198
3368
|
|
|
4199
|
-
const
|
|
4200
|
-
|
|
4201
|
-
|
|
3369
|
+
const isDigit = character => {
|
|
3370
|
+
return character !== undefined && character >= '0' && character <= '9';
|
|
3371
|
+
};
|
|
3372
|
+
const isWhitespace = character => {
|
|
3373
|
+
return character === ' ' || character === '\n' || character === '\r' || character === '\t';
|
|
3374
|
+
};
|
|
3375
|
+
const getNumberEnd = (json, start) => {
|
|
3376
|
+
let i = start;
|
|
3377
|
+
if (json[i] === '-') {
|
|
3378
|
+
i++;
|
|
4202
3379
|
}
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
}
|
|
4209
|
-
|
|
3380
|
+
if (json[i] === '0') {
|
|
3381
|
+
i++;
|
|
3382
|
+
} else {
|
|
3383
|
+
if (!isDigit(json[i])) {
|
|
3384
|
+
return start;
|
|
3385
|
+
}
|
|
3386
|
+
while (isDigit(json[i])) {
|
|
3387
|
+
i++;
|
|
3388
|
+
}
|
|
4210
3389
|
}
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
3390
|
+
if (json[i] === '.') {
|
|
3391
|
+
const decimalStart = i;
|
|
3392
|
+
i++;
|
|
3393
|
+
if (!isDigit(json[i])) {
|
|
3394
|
+
return decimalStart;
|
|
3395
|
+
}
|
|
3396
|
+
while (isDigit(json[i])) {
|
|
3397
|
+
i++;
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
if (json[i] === 'e' || json[i] === 'E') {
|
|
3401
|
+
const exponentStart = i;
|
|
3402
|
+
i++;
|
|
3403
|
+
if (json[i] === '+' || json[i] === '-') {
|
|
3404
|
+
i++;
|
|
3405
|
+
}
|
|
3406
|
+
if (!isDigit(json[i])) {
|
|
3407
|
+
return exponentStart;
|
|
3408
|
+
}
|
|
3409
|
+
while (isDigit(json[i])) {
|
|
3410
|
+
i++;
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
return i;
|
|
4215
3414
|
};
|
|
4216
|
-
|
|
4217
|
-
const numberRegex = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/;
|
|
4218
|
-
const whitespaceRegex = /\s/u;
|
|
4219
|
-
const getTokenSegments = json => {
|
|
4220
|
-
let segments = [];
|
|
3415
|
+
const forEachTokenSegment = (json, onToken) => {
|
|
4221
3416
|
let i = 0;
|
|
4222
3417
|
while (i < json.length) {
|
|
4223
3418
|
const character = json[i];
|
|
@@ -4236,40 +3431,38 @@ const getTokenSegments = json => {
|
|
|
4236
3431
|
}
|
|
4237
3432
|
i++;
|
|
4238
3433
|
}
|
|
4239
|
-
const tokenValue = json.slice(start, i);
|
|
4240
3434
|
let lookAheadIndex = i;
|
|
4241
|
-
while (lookAheadIndex < json.length &&
|
|
3435
|
+
while (lookAheadIndex < json.length && isWhitespace(json[lookAheadIndex])) {
|
|
4242
3436
|
lookAheadIndex++;
|
|
4243
3437
|
}
|
|
4244
3438
|
const className = json[lookAheadIndex] === ':' ? TokenKey : TokenString;
|
|
4245
|
-
|
|
3439
|
+
onToken(className, json.slice(start, i));
|
|
4246
3440
|
continue;
|
|
4247
3441
|
}
|
|
4248
|
-
const
|
|
4249
|
-
if (
|
|
4250
|
-
|
|
4251
|
-
i
|
|
3442
|
+
const numberEnd = getNumberEnd(json, i);
|
|
3443
|
+
if (numberEnd > i) {
|
|
3444
|
+
onToken(TokenNumeric, json.slice(i, numberEnd));
|
|
3445
|
+
i = numberEnd;
|
|
4252
3446
|
continue;
|
|
4253
3447
|
}
|
|
4254
3448
|
if (json.startsWith('true', i)) {
|
|
4255
|
-
|
|
3449
|
+
onToken(TokenBoolean, 'true');
|
|
4256
3450
|
i += 4;
|
|
4257
3451
|
continue;
|
|
4258
3452
|
}
|
|
4259
3453
|
if (json.startsWith('false', i)) {
|
|
4260
|
-
|
|
3454
|
+
onToken(TokenBoolean, 'false');
|
|
4261
3455
|
i += 5;
|
|
4262
3456
|
continue;
|
|
4263
3457
|
}
|
|
4264
3458
|
if (json.startsWith('null', i)) {
|
|
4265
|
-
|
|
3459
|
+
onToken(TokenBoolean, 'null');
|
|
4266
3460
|
i += 4;
|
|
4267
3461
|
continue;
|
|
4268
3462
|
}
|
|
4269
|
-
|
|
3463
|
+
onToken(TokenText, character);
|
|
4270
3464
|
i++;
|
|
4271
3465
|
}
|
|
4272
|
-
return segments;
|
|
4273
3466
|
};
|
|
4274
3467
|
|
|
4275
3468
|
const getJsonLines = value => {
|
|
@@ -4280,25 +3473,34 @@ const getJsonLines = value => {
|
|
|
4280
3473
|
value: String(json)
|
|
4281
3474
|
}]];
|
|
4282
3475
|
}
|
|
4283
|
-
const segments = getTokenSegments(json);
|
|
4284
3476
|
const lines = [];
|
|
4285
3477
|
let currentLine = [];
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
3478
|
+
const pushLineSegment = (className, lineValue) => {
|
|
3479
|
+
if (!lineValue) {
|
|
3480
|
+
return;
|
|
3481
|
+
}
|
|
3482
|
+
const lastSegment = currentLine.at(-1);
|
|
3483
|
+
if (lastSegment && lastSegment.className === className) {
|
|
3484
|
+
lastSegment.value += lineValue;
|
|
3485
|
+
return;
|
|
3486
|
+
}
|
|
3487
|
+
currentLine.push({
|
|
3488
|
+
className,
|
|
3489
|
+
value: lineValue
|
|
3490
|
+
});
|
|
3491
|
+
};
|
|
3492
|
+
forEachTokenSegment(json, (className, segmentValue) => {
|
|
3493
|
+
let start = 0;
|
|
3494
|
+
for (let i = 0; i < segmentValue.length; i++) {
|
|
3495
|
+
if (segmentValue[i] === '\n') {
|
|
3496
|
+
pushLineSegment(className, segmentValue.slice(start, i));
|
|
4297
3497
|
lines.push(currentLine);
|
|
4298
3498
|
currentLine = [];
|
|
3499
|
+
start = i + 1;
|
|
4299
3500
|
}
|
|
4300
3501
|
}
|
|
4301
|
-
|
|
3502
|
+
pushLineSegment(className, segmentValue.slice(start));
|
|
3503
|
+
});
|
|
4302
3504
|
lines.push(currentLine);
|
|
4303
3505
|
return lines;
|
|
4304
3506
|
};
|
|
@@ -4357,6 +3559,33 @@ const hasOwn = (event, key) => {
|
|
|
4357
3559
|
const isChatMessageUpdatedEvent = event => {
|
|
4358
3560
|
return event.type === 'chat-message-updated';
|
|
4359
3561
|
};
|
|
3562
|
+
const isChatMessageAddedEvent = event => {
|
|
3563
|
+
return event.type === 'chat-message-added';
|
|
3564
|
+
};
|
|
3565
|
+
const getPreviewMessageText = event => {
|
|
3566
|
+
if (isChatMessageUpdatedEvent(event) && typeof event.text === 'string') {
|
|
3567
|
+
return event.text;
|
|
3568
|
+
}
|
|
3569
|
+
if (!isChatMessageAddedEvent(event)) {
|
|
3570
|
+
return undefined;
|
|
3571
|
+
}
|
|
3572
|
+
const {
|
|
3573
|
+
message
|
|
3574
|
+
} = event;
|
|
3575
|
+
if (!message || typeof message !== 'object') {
|
|
3576
|
+
return undefined;
|
|
3577
|
+
}
|
|
3578
|
+
if (!Object.hasOwn(message, 'text')) {
|
|
3579
|
+
return undefined;
|
|
3580
|
+
}
|
|
3581
|
+
const {
|
|
3582
|
+
text
|
|
3583
|
+
} = message;
|
|
3584
|
+
if (typeof text !== 'string') {
|
|
3585
|
+
return undefined;
|
|
3586
|
+
}
|
|
3587
|
+
return text;
|
|
3588
|
+
};
|
|
4360
3589
|
const getPreviewName = event => {
|
|
4361
3590
|
if (typeof event.name === 'string' && event.name) {
|
|
4362
3591
|
return event.name;
|
|
@@ -4376,8 +3605,9 @@ const shouldIncludeArguments = (event, name) => {
|
|
|
4376
3605
|
return true;
|
|
4377
3606
|
};
|
|
4378
3607
|
const getPreviewEvent = event => {
|
|
4379
|
-
|
|
4380
|
-
|
|
3608
|
+
const previewMessageText = getPreviewMessageText(event);
|
|
3609
|
+
if (previewMessageText !== undefined) {
|
|
3610
|
+
return previewMessageText;
|
|
4381
3611
|
}
|
|
4382
3612
|
const name = getPreviewName(event);
|
|
4383
3613
|
const previewEvent = {
|
|
@@ -4462,9 +3692,12 @@ const formatPercent = value => {
|
|
|
4462
3692
|
return `${Number(value.toFixed(3))}%`;
|
|
4463
3693
|
};
|
|
4464
3694
|
|
|
4465
|
-
const getBucketUnitDom = unitCount => {
|
|
3695
|
+
const getBucketUnitDom = (unitCount, presetValue) => {
|
|
4466
3696
|
if (unitCount === 0) {
|
|
4467
3697
|
return [{
|
|
3698
|
+
...(presetValue ? {
|
|
3699
|
+
'data-value': presetValue
|
|
3700
|
+
} : {}),
|
|
4468
3701
|
childCount: 0,
|
|
4469
3702
|
className: joinClassNames(ChatDebugViewTimelineBucketUnit, ChatDebugViewTimelineBucketUnitEmpty),
|
|
4470
3703
|
type: Div
|
|
@@ -4473,6 +3706,9 @@ const getBucketUnitDom = unitCount => {
|
|
|
4473
3706
|
return Array.from({
|
|
4474
3707
|
length: unitCount
|
|
4475
3708
|
}).fill({
|
|
3709
|
+
...(presetValue ? {
|
|
3710
|
+
'data-value': presetValue
|
|
3711
|
+
} : {}),
|
|
4476
3712
|
childCount: 0,
|
|
4477
3713
|
className: ChatDebugViewTimelineBucketUnit,
|
|
4478
3714
|
type: Div
|
|
@@ -4482,23 +3718,17 @@ const getBucketUnitDom = unitCount => {
|
|
|
4482
3718
|
const getBucketDom = bucket => {
|
|
4483
3719
|
const presetValue = `${formatTimelinePresetValue(bucket.startSeconds)}:${formatTimelinePresetValue(bucket.endSeconds)}`;
|
|
4484
3720
|
return [{
|
|
4485
|
-
childCount:
|
|
3721
|
+
childCount: 1,
|
|
4486
3722
|
className: joinClassNames(ChatDebugViewTimelineBucket, bucket.isSelected && ChatDebugViewTimelineBucketSelected),
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
childCount: 0,
|
|
4491
|
-
className: ChatDebugViewTimelinePresetInput,
|
|
4492
|
-
inputType: 'radio',
|
|
4493
|
-
name: TimelineRangePreset,
|
|
4494
|
-
onChange: HandleTimelineRangePreset,
|
|
4495
|
-
type: Input,
|
|
4496
|
-
value: presetValue
|
|
3723
|
+
'data-value': presetValue,
|
|
3724
|
+
onClick: HandleTimelineRangePreset,
|
|
3725
|
+
type: Div
|
|
4497
3726
|
}, {
|
|
4498
3727
|
childCount: bucket.unitCount === 0 ? 1 : bucket.unitCount,
|
|
4499
3728
|
className: joinClassNames(ChatDebugViewTimelineBucketBar, bucket.isSelected && ChatDebugViewTimelineBucketBarSelected),
|
|
3729
|
+
'data-value': presetValue,
|
|
4500
3730
|
type: Div
|
|
4501
|
-
}, ...getBucketUnitDom(bucket.unitCount)];
|
|
3731
|
+
}, ...getBucketUnitDom(bucket.unitCount, presetValue)];
|
|
4502
3732
|
};
|
|
4503
3733
|
|
|
4504
3734
|
const getEffectiveTimelineRange = (timelineStartSeconds, timelineEndSeconds, timelineSelectionActive, timelineSelectionAnchorSeconds, timelineSelectionFocusSeconds) => {
|
|
@@ -4759,10 +3989,10 @@ const render2 = (uid, diffResult) => {
|
|
|
4759
3989
|
const renderEventListeners = () => {
|
|
4760
3990
|
return [{
|
|
4761
3991
|
name: HandleEventRowClick,
|
|
4762
|
-
params: ['handleEventRowClick', 'event.target.dataset.index',
|
|
3992
|
+
params: ['handleEventRowClick', 'event.target.dataset.index', Button]
|
|
4763
3993
|
}, {
|
|
4764
3994
|
name: HandleTableBodyContextMenu,
|
|
4765
|
-
params: ['handleTableBodyContextMenu'],
|
|
3995
|
+
params: ['handleTableBodyContextMenu', ClientX, ClientY],
|
|
4766
3996
|
preventDefault: true
|
|
4767
3997
|
}, {
|
|
4768
3998
|
name: HandleFilterInput,
|
|
@@ -4775,10 +4005,13 @@ const renderEventListeners = () => {
|
|
|
4775
4005
|
params: ['handleDetailTab', TargetValue]
|
|
4776
4006
|
}, {
|
|
4777
4007
|
name: HandleTimelineRangePreset,
|
|
4778
|
-
params: ['handleTimelineRangePreset',
|
|
4008
|
+
params: ['handleTimelineRangePreset', 'event.target.dataset.value']
|
|
4779
4009
|
}, {
|
|
4780
4010
|
name: HandleCloseDetails,
|
|
4781
4011
|
params: ['handleCloseDetails']
|
|
4012
|
+
}, {
|
|
4013
|
+
name: HandleClickRefresh,
|
|
4014
|
+
params: ['handleClickRefresh']
|
|
4782
4015
|
}, {
|
|
4783
4016
|
name: HandleSashPointerDown,
|
|
4784
4017
|
params: ['handleSashPointerDown', ClientX, ClientY],
|
|
@@ -4871,31 +4104,15 @@ const setEvents = (state, events) => {
|
|
|
4871
4104
|
};
|
|
4872
4105
|
};
|
|
4873
4106
|
|
|
4874
|
-
const setIndexedDbSupportForTest = supported => {
|
|
4875
|
-
return setIndexedDbSupportOverride(supported);
|
|
4876
|
-
};
|
|
4877
|
-
|
|
4878
4107
|
const setSessionIdDependencies = {
|
|
4879
4108
|
listChatViewEvents: listChatViewEvents
|
|
4880
4109
|
};
|
|
4881
4110
|
const setSessionId = async (state, sessionId) => {
|
|
4882
|
-
const result = await setSessionIdDependencies.listChatViewEvents(sessionId, state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionIdIndexName
|
|
4883
|
-
if (result.type === 'not-supported') {
|
|
4884
|
-
return {
|
|
4885
|
-
...state,
|
|
4886
|
-
errorMessage: getIndexedDbNotSupportedMessage(),
|
|
4887
|
-
events: [],
|
|
4888
|
-
initial: false,
|
|
4889
|
-
selectedEvent: null,
|
|
4890
|
-
selectedEventId: null,
|
|
4891
|
-
selectedEventIndex: null,
|
|
4892
|
-
sessionId
|
|
4893
|
-
};
|
|
4894
|
-
}
|
|
4111
|
+
const result = await setSessionIdDependencies.listChatViewEvents(sessionId, state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionIdIndexName);
|
|
4895
4112
|
if (result.type === 'error') {
|
|
4896
4113
|
return {
|
|
4897
4114
|
...state,
|
|
4898
|
-
errorMessage: getFailedToLoadMessage(sessionId),
|
|
4115
|
+
errorMessage: getFailedToLoadMessage(sessionId, result.error),
|
|
4899
4116
|
events: [],
|
|
4900
4117
|
initial: false,
|
|
4901
4118
|
selectedEvent: null,
|
|
@@ -4923,6 +4140,8 @@ const commandMap = {
|
|
|
4923
4140
|
'ChatDebug.create': create,
|
|
4924
4141
|
'ChatDebug.diff2': diff2,
|
|
4925
4142
|
'ChatDebug.getCommandIds': getCommandIds,
|
|
4143
|
+
'ChatDebug.getMenuIds': getMenuIds,
|
|
4144
|
+
'ChatDebug.handleClickRefresh': wrapCommand(handleClickRefresh),
|
|
4926
4145
|
'ChatDebug.handleCloseDetails': wrapCommand(handleCloseDetails),
|
|
4927
4146
|
'ChatDebug.handleDetailsContextMenu': wrapCommand(handleDetailsContextMenu),
|
|
4928
4147
|
'ChatDebug.handleDetailTab': wrapCommand(handleDetailTab),
|
|
@@ -4954,17 +4173,28 @@ const commandMap = {
|
|
|
4954
4173
|
'ChatDebug.resize': wrapCommand(resize),
|
|
4955
4174
|
'ChatDebug.saveState': wrapGetter(saveState),
|
|
4956
4175
|
'ChatDebug.setEvents': wrapCommand(setEvents),
|
|
4957
|
-
'ChatDebug.setIndexedDbSupportForTest': setIndexedDbSupportForTest,
|
|
4958
4176
|
'ChatDebug.setSessionId': wrapCommand(setSessionId),
|
|
4959
4177
|
'ChatDebug.terminate': terminate
|
|
4960
4178
|
};
|
|
4961
4179
|
|
|
4180
|
+
const sendMessagePortToChatStorageWorker = async port => {
|
|
4181
|
+
await sendMessagePortToChatStorageWorker$1(port);
|
|
4182
|
+
};
|
|
4183
|
+
const initializeChatStorageWorker = async () => {
|
|
4184
|
+
const rpc = await create$4({
|
|
4185
|
+
commandMap: {},
|
|
4186
|
+
send: sendMessagePortToChatStorageWorker
|
|
4187
|
+
});
|
|
4188
|
+
set$2(rpc);
|
|
4189
|
+
};
|
|
4190
|
+
|
|
4962
4191
|
const listen = async () => {
|
|
4963
4192
|
registerCommands(commandMap);
|
|
4964
|
-
const
|
|
4193
|
+
const r = await create$3({
|
|
4965
4194
|
commandMap: commandMap
|
|
4966
4195
|
});
|
|
4967
|
-
|
|
4196
|
+
set$1(r);
|
|
4197
|
+
await initializeChatStorageWorker();
|
|
4968
4198
|
};
|
|
4969
4199
|
|
|
4970
4200
|
const main = async () => {
|