@lvce-editor/output-view 1.19.0 → 2.1.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.
@@ -225,8 +225,8 @@ const getModuleNotFoundError = stderr => {
225
225
  const messageIndex = lines.findIndex(isModuleNotFoundMessage);
226
226
  const message = lines[messageIndex];
227
227
  return {
228
- message,
229
- code: ERR_MODULE_NOT_FOUND
228
+ code: ERR_MODULE_NOT_FOUND,
229
+ message
230
230
  };
231
231
  };
232
232
  const isModuleNotFoundError = stderr => {
@@ -249,14 +249,14 @@ const isUnhelpfulNativeModuleError = stderr => {
249
249
  const getNativeModuleErrorMessage = stderr => {
250
250
  const message = getMessageCodeBlock(stderr);
251
251
  return {
252
- message: `Incompatible native node module: ${message}`,
253
- code: E_INCOMPATIBLE_NATIVE_MODULE
252
+ code: E_INCOMPATIBLE_NATIVE_MODULE,
253
+ message: `Incompatible native node module: ${message}`
254
254
  };
255
255
  };
256
256
  const getModuleSyntaxError = () => {
257
257
  return {
258
- message: `ES Modules are not supported in electron`,
259
- code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
258
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON,
259
+ message: `ES Modules are not supported in electron`
260
260
  };
261
261
  };
262
262
  const getHelpfulChildProcessError = (stdout, stderr) => {
@@ -275,8 +275,8 @@ const getHelpfulChildProcessError = (stdout, stderr) => {
275
275
  rest
276
276
  } = getDetails(lines);
277
277
  return {
278
- message: actualMessage,
279
278
  code: '',
279
+ message: actualMessage,
280
280
  stack: rest
281
281
  };
282
282
  };
@@ -286,8 +286,8 @@ class IpcError extends VError {
286
286
  if (stdout || stderr) {
287
287
  // @ts-ignore
288
288
  const {
289
- message,
290
289
  code,
290
+ message,
291
291
  stack
292
292
  } = getHelpfulChildProcessError(stdout, stderr);
293
293
  const cause = new Error(message);
@@ -348,8 +348,8 @@ const wrap$f = global => {
348
348
  };
349
349
  const waitForFirstMessage = async port => {
350
350
  const {
351
- resolve,
352
- promise
351
+ promise,
352
+ resolve
353
353
  } = Promise.withResolvers();
354
354
  port.addEventListener('message', resolve, {
355
355
  once: true
@@ -369,8 +369,8 @@ const listen$6 = async () => {
369
369
  const type = firstMessage.params[0];
370
370
  if (type === 'message-port') {
371
371
  parentIpc.send({
372
- jsonrpc: '2.0',
373
372
  id: firstMessage.id,
373
+ jsonrpc: '2.0',
374
374
  result: null
375
375
  });
376
376
  parentIpc.dispose();
@@ -427,8 +427,8 @@ const removeListener = (emitter, type, callback) => {
427
427
  };
428
428
  const getFirstEvent = (eventEmitter, eventMap) => {
429
429
  const {
430
- resolve,
431
- promise
430
+ promise,
431
+ resolve
432
432
  } = Promise.withResolvers();
433
433
  const listenerMap = Object.create(null);
434
434
  const cleanup = value => {
@@ -440,8 +440,8 @@ const getFirstEvent = (eventEmitter, eventMap) => {
440
440
  for (const [event, type] of Object.entries(eventMap)) {
441
441
  const listener = event => {
442
442
  cleanup({
443
- type,
444
- event
443
+ event,
444
+ type
445
445
  });
446
446
  };
447
447
  addListener(eventEmitter, event, listener);
@@ -450,9 +450,9 @@ const getFirstEvent = (eventEmitter, eventMap) => {
450
450
  return promise;
451
451
  };
452
452
  const Message$1 = 3;
453
- const create$5$1 = async ({
454
- messagePort,
455
- isMessagePortOpen
453
+ const create$5 = async ({
454
+ isMessagePortOpen,
455
+ messagePort
456
456
  }) => {
457
457
  if (!isMessagePort(messagePort)) {
458
458
  throw new IpcError('port must be of type MessagePort');
@@ -465,8 +465,8 @@ const create$5$1 = async ({
465
465
  });
466
466
  messagePort.start();
467
467
  const {
468
- type,
469
- event
468
+ event,
469
+ type
470
470
  } = await eventPromise;
471
471
  if (type !== Message$1) {
472
472
  throw new IpcError('Failed to wait for ipc message');
@@ -501,61 +501,19 @@ const wrap$5 = messagePort => {
501
501
  };
502
502
  const IpcParentWithMessagePort$1 = {
503
503
  __proto__: null,
504
- create: create$5$1,
504
+ create: create$5,
505
505
  signal: signal$1,
506
506
  wrap: wrap$5
507
507
  };
508
508
 
509
- const Two = '2.0';
510
- const create$4$1 = (method, params) => {
511
- return {
512
- jsonrpc: Two,
513
- method,
514
- params
515
- };
516
- };
509
+ const Two$1 = '2.0';
517
510
  const callbacks = Object.create(null);
518
- const set$4 = (id, fn) => {
519
- callbacks[id] = fn;
520
- };
521
511
  const get$2 = id => {
522
512
  return callbacks[id];
523
513
  };
524
514
  const remove$1 = id => {
525
515
  delete callbacks[id];
526
516
  };
527
- let id = 0;
528
- const create$3$1 = () => {
529
- return ++id;
530
- };
531
- const registerPromise = () => {
532
- const id = create$3$1();
533
- const {
534
- resolve,
535
- promise
536
- } = Promise.withResolvers();
537
- set$4(id, resolve);
538
- return {
539
- id,
540
- promise
541
- };
542
- };
543
- const create$2$1 = (method, params) => {
544
- const {
545
- id,
546
- promise
547
- } = registerPromise();
548
- const message = {
549
- jsonrpc: Two,
550
- method,
551
- params,
552
- id
553
- };
554
- return {
555
- message,
556
- promise
557
- };
558
- };
559
517
  class JsonRpcError extends Error {
560
518
  constructor(message) {
561
519
  super(message);
@@ -749,9 +707,9 @@ const getErrorProperty = (error, prettyError) => {
749
707
  }
750
708
  };
751
709
  };
752
- const create$1$1 = (id, error) => {
710
+ const create$1$2 = (id, error) => {
753
711
  return {
754
- jsonrpc: Two,
712
+ jsonrpc: Two$1,
755
713
  id,
756
714
  error
757
715
  };
@@ -760,22 +718,22 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
760
718
  const prettyError = preparePrettyError(error);
761
719
  logError(error, prettyError);
762
720
  const errorProperty = getErrorProperty(error, prettyError);
763
- return create$1$1(id, errorProperty);
721
+ return create$1$2(id, errorProperty);
764
722
  };
765
- const create$6 = (message, result) => {
723
+ const create$3 = (message, result) => {
766
724
  return {
767
- jsonrpc: Two,
725
+ jsonrpc: Two$1,
768
726
  id: message.id,
769
727
  result: result ?? null
770
728
  };
771
729
  };
772
730
  const getSuccessResponse = (message, result) => {
773
731
  const resultProperty = result ?? null;
774
- return create$6(message, resultProperty);
732
+ return create$3(message, resultProperty);
775
733
  };
776
734
  const getErrorResponseSimple = (id, error) => {
777
735
  return {
778
- jsonrpc: Two,
736
+ jsonrpc: Two$1,
779
737
  id,
780
738
  error: {
781
739
  code: Custom,
@@ -862,29 +820,6 @@ const handleJsonRpcMessage = async (...args) => {
862
820
  }
863
821
  throw new JsonRpcError('unexpected message');
864
822
  };
865
- const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
866
- const {
867
- message,
868
- promise
869
- } = create$2$1(method, params);
870
- if (useSendAndTransfer && ipc.sendAndTransfer) {
871
- ipc.sendAndTransfer(message);
872
- } else {
873
- ipc.send(message);
874
- }
875
- const responseMessage = await promise;
876
- return unwrapJsonRpcResult(responseMessage);
877
- };
878
- const send = (transport, method, ...params) => {
879
- const message = create$4$1(method, params);
880
- transport.send(message);
881
- };
882
- const invoke$2 = (ipc, method, ...params) => {
883
- return invokeHelper(ipc, method, params, false);
884
- };
885
- const invokeAndTransfer = (ipc, method, ...params) => {
886
- return invokeHelper(ipc, method, params, true);
887
- };
888
823
 
889
824
  class CommandNotFoundError extends Error {
890
825
  constructor(command) {
@@ -907,24 +842,87 @@ const execute = (command, ...args) => {
907
842
  return fn(...args);
908
843
  };
909
844
 
845
+ const Two = '2.0';
846
+ const create$s = (method, params) => {
847
+ return {
848
+ jsonrpc: Two,
849
+ method,
850
+ params
851
+ };
852
+ };
853
+ const create$r = (id, method, params) => {
854
+ const message = {
855
+ id,
856
+ jsonrpc: Two,
857
+ method,
858
+ params
859
+ };
860
+ return message;
861
+ };
862
+ let id = 0;
863
+ const create$q = () => {
864
+ return ++id;
865
+ };
866
+
867
+ /* eslint-disable n/no-unsupported-features/es-syntax */
868
+
869
+ const registerPromise = map => {
870
+ const id = create$q();
871
+ const {
872
+ promise,
873
+ resolve
874
+ } = Promise.withResolvers();
875
+ map[id] = resolve;
876
+ return {
877
+ id,
878
+ promise
879
+ };
880
+ };
881
+
882
+ // @ts-ignore
883
+ const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer) => {
884
+ const {
885
+ id,
886
+ promise
887
+ } = registerPromise(callbacks);
888
+ const message = create$r(id, method, params);
889
+ if (useSendAndTransfer && ipc.sendAndTransfer) {
890
+ ipc.sendAndTransfer(message);
891
+ } else {
892
+ ipc.send(message);
893
+ }
894
+ const responseMessage = await promise;
895
+ return unwrapJsonRpcResult(responseMessage);
896
+ };
910
897
  const createRpc = ipc => {
898
+ const callbacks = Object.create(null);
899
+ ipc._resolve = (id, response) => {
900
+ const fn = callbacks[id];
901
+ if (!fn) {
902
+ console.warn(`callback ${id} may already be disposed`);
903
+ return;
904
+ }
905
+ fn(response);
906
+ delete callbacks[id];
907
+ };
911
908
  const rpc = {
909
+ async dispose() {
910
+ await ipc?.dispose();
911
+ },
912
+ invoke(method, ...params) {
913
+ return invokeHelper(callbacks, ipc, method, params, false);
914
+ },
915
+ invokeAndTransfer(method, ...params) {
916
+ return invokeHelper(callbacks, ipc, method, params, true);
917
+ },
912
918
  // @ts-ignore
913
919
  ipc,
914
920
  /**
915
921
  * @deprecated
916
922
  */
917
923
  send(method, ...params) {
918
- send(ipc, method, ...params);
919
- },
920
- invoke(method, ...params) {
921
- return invoke$2(ipc, method, ...params);
922
- },
923
- invokeAndTransfer(method, ...params) {
924
- return invokeAndTransfer(ipc, method, ...params);
925
- },
926
- async dispose() {
927
- await ipc?.dispose();
924
+ const message = create$s(method, params);
925
+ ipc.send(message);
928
926
  }
929
927
  };
930
928
  return rpc;
@@ -941,7 +939,7 @@ const logError = () => {
941
939
  const handleMessage = event => {
942
940
  const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
943
941
  const actualExecute = event?.target?.execute || execute;
944
- return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
942
+ return handleJsonRpcMessage(event.target, event.data, actualExecute, event.target._resolve, preparePrettyError, logError, actualRequiresSocket);
945
943
  };
946
944
  const handleIpc = ipc => {
947
945
  if ('addEventListener' in ipc) {
@@ -959,15 +957,16 @@ const listen$1 = async (module, options) => {
959
957
  const ipc = module.wrap(rawIpc);
960
958
  return ipc;
961
959
  };
962
- const create$5 = async ({
960
+ const create$4 = async ({
963
961
  commandMap,
962
+ isMessagePortOpen = true,
964
963
  messagePort
965
964
  }) => {
966
965
  // TODO create a commandMap per rpc instance
967
966
  register(commandMap);
968
967
  const rawIpc = await IpcParentWithMessagePort$1.create({
969
- messagePort,
970
- isMessagePortOpen: true
968
+ isMessagePortOpen,
969
+ messagePort
971
970
  });
972
971
  const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
973
972
  handleIpc(ipc);
@@ -975,8 +974,9 @@ const create$5 = async ({
975
974
  messagePort.start();
976
975
  return rpc;
977
976
  };
978
- const create$3 = async ({
977
+ const create$2$1 = async ({
979
978
  commandMap,
979
+ isMessagePortOpen,
980
980
  send
981
981
  }) => {
982
982
  const {
@@ -984,16 +984,17 @@ const create$3 = async ({
984
984
  port2
985
985
  } = new MessageChannel();
986
986
  await send(port1);
987
- return create$5({
987
+ return create$4({
988
988
  commandMap,
989
+ isMessagePortOpen,
989
990
  messagePort: port2
990
991
  });
991
992
  };
992
993
  const TransferMessagePortRpcParent = {
993
994
  __proto__: null,
994
- create: create$3
995
+ create: create$2$1
995
996
  };
996
- const create$4 = async ({
997
+ const create$1$1 = async ({
997
998
  commandMap
998
999
  }) => {
999
1000
  // TODO create a commandMap per rpc instance
@@ -1005,105 +1006,67 @@ const create$4 = async ({
1005
1006
  };
1006
1007
  const WebWorkerRpcClient = {
1007
1008
  __proto__: null,
1008
- create: create$4
1009
+ create: create$1$1
1009
1010
  };
1010
-
1011
- const toCommandId = key => {
1012
- const dotIndex = key.indexOf('.');
1013
- return key.slice(dotIndex + 1);
1014
- };
1015
- const create$2 = () => {
1016
- const states = Object.create(null);
1017
- const commandMapRef = {};
1018
- return {
1019
- get(uid) {
1020
- return states[uid];
1021
- },
1022
- set(uid, oldState, newState) {
1023
- states[uid] = {
1024
- oldState,
1025
- newState
1026
- };
1027
- },
1028
- dispose(uid) {
1029
- delete states[uid];
1030
- },
1031
- getKeys() {
1032
- return Object.keys(states).map(key => {
1033
- return Number.parseInt(key);
1034
- });
1035
- },
1036
- clear() {
1037
- for (const key of Object.keys(states)) {
1038
- delete states[key];
1039
- }
1040
- },
1041
- wrapCommand(fn) {
1042
- const wrapped = async (uid, ...args) => {
1043
- const {
1044
- newState
1045
- } = states[uid];
1046
- const newerState = await fn(newState, ...args);
1047
- if (newState === newerState) {
1048
- return;
1049
- }
1050
- const latest = states[uid];
1051
- states[uid] = {
1052
- oldState: latest.oldState,
1053
- newState: newerState
1054
- };
1055
- };
1056
- return wrapped;
1057
- },
1058
- wrapGetter(fn) {
1059
- const wrapped = (uid, ...args) => {
1060
- const {
1061
- newState
1062
- } = states[uid];
1063
- return fn(newState, ...args);
1064
- };
1065
- return wrapped;
1066
- },
1067
- diff(uid, modules, numbers) {
1068
- const {
1069
- oldState,
1070
- newState
1071
- } = states[uid];
1072
- const diffResult = [];
1073
- for (let i = 0; i < modules.length; i++) {
1074
- const fn = modules[i];
1075
- if (!fn(oldState, newState)) {
1076
- diffResult.push(numbers[i]);
1077
- }
1078
- }
1079
- return diffResult;
1080
- },
1081
- getCommandIds() {
1082
- const keys = Object.keys(commandMapRef);
1083
- const ids = keys.map(toCommandId);
1084
- return ids;
1085
- },
1086
- registerCommands(commandMap) {
1087
- Object.assign(commandMapRef, commandMap);
1011
+ const createMockRpc = ({
1012
+ commandMap
1013
+ }) => {
1014
+ const invocations = [];
1015
+ const invoke = (method, ...params) => {
1016
+ invocations.push([method, ...params]);
1017
+ const command = commandMap[method];
1018
+ if (!command) {
1019
+ throw new Error(`command ${method} not found`);
1088
1020
  }
1021
+ return command(...params);
1089
1022
  };
1023
+ const mockRpc = {
1024
+ invocations,
1025
+ invoke,
1026
+ invokeAndTransfer: invoke
1027
+ };
1028
+ return mockRpc;
1090
1029
  };
1091
- const terminate = () => {
1092
- globalThis.close();
1093
- };
1030
+
1031
+ const ToolBar = 'toolbar';
1032
+
1033
+ const Button = 1;
1034
+ const Div = 4;
1035
+ const Input = 6;
1036
+ const Text$1 = 12;
1037
+ const A = 53;
1038
+ const Select$1 = 63;
1039
+ const Option$1 = 64;
1040
+
1041
+ const Space = 9;
1042
+ const PageUp = 10;
1043
+ const PageDown = 11;
1044
+ const End = 255;
1045
+ const Home = 12;
1046
+ const LeftArrow = 13;
1047
+ const UpArrow = 14;
1048
+ const RightArrow = 15;
1049
+ const DownArrow = 16;
1050
+
1051
+ const ExtensionHostWorker = 44;
1052
+ const FileSystemWorker$1 = 209;
1053
+ const OutputWorker = 7001;
1054
+ const RendererWorker = 1;
1094
1055
 
1095
1056
  const rpcs = Object.create(null);
1096
- const set$g = (id, rpc) => {
1057
+ const set$6 = (id, rpc) => {
1097
1058
  rpcs[id] = rpc;
1098
1059
  };
1099
1060
  const get$1 = id => {
1100
1061
  return rpcs[id];
1101
1062
  };
1102
1063
 
1103
- /* eslint-disable @typescript-eslint/explicit-function-return-type */
1104
-
1105
- const create$1 = rpcId => {
1064
+ const create$2 = rpcId => {
1106
1065
  return {
1066
+ async dispose() {
1067
+ const rpc = get$1(rpcId);
1068
+ await rpc.dispose();
1069
+ },
1107
1070
  // @ts-ignore
1108
1071
  invoke(method, ...params) {
1109
1072
  const rpc = get$1(rpcId);
@@ -1117,225 +1080,351 @@ const create$1 = rpcId => {
1117
1080
  return rpc.invokeAndTransfer(method, ...params);
1118
1081
  },
1119
1082
  set(rpc) {
1120
- set$g(rpcId, rpc);
1121
- },
1122
- async dispose() {
1123
- const rpc = get$1(rpcId);
1124
- await rpc.dispose();
1083
+ set$6(rpcId, rpc);
1125
1084
  }
1126
1085
  };
1127
1086
  };
1128
- const DebugWorker$1 = 55;
1129
- const EditorWorker$1 = 99;
1130
- const ExtensionHostWorker = 44;
1131
- const MainProcess$1 = -5;
1132
- const RendererWorker$1 = 1;
1133
- const RendererProcess$1 = 1670;
1134
- const SearchProcess$1 = 77;
1135
- const SearchProcessElectron = 2;
1136
- const SharedProcess$1 = 1;
1137
- const SourceControlWorker = 66;
1138
- const EmbedsProcess$1 = 207;
1139
- const EmbedsWorker = 208;
1140
- const FileSystemWorker$1 = 209;
1141
- const FileSystemProcess$1 = 210;
1142
- const MarkdownWorker$1 = 300;
1143
- const CompletionWorker = 301;
1144
- const ColorPickerWorker = 302;
1145
- const SourceActionWorker = 303;
1146
- const ErrorWorker$1 = 3308;
1147
- const SyntaxHighlightingWorker$1 = 3309;
1148
- const ClipBoardWorker$1 = 3400;
1149
- const ClipBoardProcess$1 = 3401;
1150
- const ExtensionDetailWorker = 3402;
1151
- const ProblemsWorker = 3403;
1152
- const OutputWorker = 7001;
1153
- const RpcId = {
1154
- __proto__: null,
1155
- ClipBoardProcess: ClipBoardProcess$1,
1156
- ClipBoardWorker: ClipBoardWorker$1,
1157
- ColorPickerWorker,
1158
- CompletionWorker,
1159
- DebugWorker: DebugWorker$1,
1160
- EditorWorker: EditorWorker$1,
1161
- EmbedsProcess: EmbedsProcess$1,
1162
- EmbedsWorker,
1163
- ErrorWorker: ErrorWorker$1,
1164
- ExtensionDetailWorker,
1165
- ExtensionHostWorker,
1166
- FileSystemProcess: FileSystemProcess$1,
1167
- FileSystemWorker: FileSystemWorker$1,
1168
- MainProcess: MainProcess$1,
1169
- MarkdownWorker: MarkdownWorker$1,
1170
- OutputWorker,
1171
- ProblemsWorker,
1172
- RendererProcess: RendererProcess$1,
1173
- RendererWorker: RendererWorker$1,
1174
- SearchProcess: SearchProcess$1,
1175
- SearchProcessElectron,
1176
- SharedProcess: SharedProcess$1,
1177
- SourceActionWorker,
1178
- SourceControlWorker,
1179
- SyntaxHighlightingWorker: SyntaxHighlightingWorker$1
1180
- };
1087
+
1181
1088
  const {
1182
- invoke: invoke$9,
1183
- set: set$9} = create$1(ExtensionHostWorker);
1089
+ dispose: dispose$1,
1090
+ invoke: invoke$3,
1091
+ invokeAndTransfer: invokeAndTransfer$2,
1092
+ set: set$5
1093
+ } = create$2(ExtensionHostWorker);
1094
+ const executeReferenceProvider = async (id, offset) => {
1095
+ // @ts-ignore
1096
+ return invoke$3('ExtensionHostReference.executeReferenceProvider', id, offset);
1097
+ };
1098
+ const executeFileReferenceProvider = async id => {
1099
+ // @ts-ignore
1100
+ return invoke$3('ExtensionHostReference.executeFileReferenceProvider', id);
1101
+ };
1102
+ const getRuntimeStatus = async extensionId => {
1103
+ // @ts-ignore
1104
+ return invoke$3('ExtensionHost.getRuntimeStatus', extensionId);
1105
+ };
1106
+ const registerMockRpc$1 = commandMap => {
1107
+ const mockRpc = createMockRpc({
1108
+ commandMap
1109
+ });
1110
+ set$5(mockRpc);
1111
+ return mockRpc;
1112
+ };
1113
+
1184
1114
  const ExtensionHost = {
1185
1115
  __proto__: null,
1186
- invoke: invoke$9,
1187
- set: set$9
1116
+ dispose: dispose$1,
1117
+ executeFileReferenceProvider,
1118
+ executeReferenceProvider,
1119
+ getRuntimeStatus,
1120
+ invoke: invoke$3,
1121
+ invokeAndTransfer: invokeAndTransfer$2,
1122
+ registerMockRpc: registerMockRpc$1,
1123
+ set: set$5
1188
1124
  };
1125
+
1189
1126
  const {
1190
- invoke: invoke$7,
1191
- invokeAndTransfer: invokeAndTransfer$7,
1192
- set: set$7,
1193
- dispose: dispose$7
1194
- } = create$1(FileSystemWorker$1);
1127
+ dispose,
1128
+ invoke: invoke$2,
1129
+ invokeAndTransfer: invokeAndTransfer$1,
1130
+ set: set$4
1131
+ } = create$2(FileSystemWorker$1);
1195
1132
  const remove = async dirent => {
1196
- return invoke$7('FileSystem.remove', dirent);
1133
+ return invoke$2('FileSystem.remove', dirent);
1197
1134
  };
1198
1135
  const readDirWithFileTypes = async uri => {
1199
- return invoke$7('FileSystem.readDirWithFileTypes', uri);
1136
+ return invoke$2('FileSystem.readDirWithFileTypes', uri);
1200
1137
  };
1201
1138
  const getPathSeparator = async root => {
1202
- // @ts-ignore
1203
- return invoke$7('FileSystem.getPathSeparator', root);
1139
+ return invoke$2('FileSystem.getPathSeparator', root);
1204
1140
  };
1205
1141
  const getRealPath = async path => {
1206
- return invoke$7('FileSystem.getRealPath', path);
1142
+ return invoke$2('FileSystem.getRealPath', path);
1207
1143
  };
1208
1144
  const stat = async dirent => {
1209
- return invoke$7('FileSystem.stat', dirent);
1145
+ return invoke$2('FileSystem.stat', dirent);
1210
1146
  };
1211
1147
  const createFile = async uri => {
1212
- return invoke$7('FileSystem.writeFile', uri, '');
1148
+ return invoke$2('FileSystem.writeFile', uri, '');
1213
1149
  };
1214
1150
  const readFile$1 = async uri => {
1215
- return invoke$7('FileSystem.readFile', uri);
1151
+ return invoke$2('FileSystem.readFile', uri);
1216
1152
  };
1217
1153
  const writeFile$1 = async (uri, content) => {
1218
- return invoke$7('FileSystem.writeFile', uri, content);
1154
+ return invoke$2('FileSystem.writeFile', uri, content);
1219
1155
  };
1220
1156
  const mkdir = async uri => {
1221
- return invoke$7('FileSystem.mkdir', uri);
1157
+ return invoke$2('FileSystem.mkdir', uri);
1222
1158
  };
1223
1159
  const rename = async (oldUri, newUri) => {
1224
- return invoke$7('FileSystem.rename', oldUri, newUri);
1160
+ return invoke$2('FileSystem.rename', oldUri, newUri);
1225
1161
  };
1226
1162
  const copy = async (oldUri, newUri) => {
1227
- return invoke$7('FileSystem.copy', oldUri, newUri);
1163
+ return invoke$2('FileSystem.copy', oldUri, newUri);
1228
1164
  };
1229
1165
  const exists = async uri => {
1230
- // @ts-ignore
1231
- return invoke$7('FileSystem.exists', uri);
1166
+ return invoke$2('FileSystem.exists', uri);
1232
1167
  };
1233
- const getFolderSize$1 = async uri => {
1234
- // @ts-ignore
1235
- return invoke$7('FileSystem.getFolderSize', uri);
1168
+ const getFolderSize = async uri => {
1169
+ return invoke$2('FileSystem.getFolderSize', uri);
1236
1170
  };
1237
1171
  const readFileAsBlob = async uri => {
1238
- // @ts-ignore
1239
- return invoke$7('FileSystem.readFileAsBlob', uri);
1172
+ return invoke$2('FileSystem.readFileAsBlob', uri);
1240
1173
  };
1241
1174
  const appendFile = async (uri, text) => {
1242
- // @ts-ignore
1243
- return invoke$7('FileSystem.appendFile', uri, text);
1175
+ return invoke$2('FileSystem.appendFile', uri, text);
1176
+ };
1177
+ const watchFile = async (watchId, uri, rpcId) => {
1178
+ await invoke$2('FileSystem.watchFile', watchId, uri, rpcId);
1179
+ };
1180
+ const unwatchFile = async watchId => {
1181
+ await invoke$2('FileSystem.unwatchFile', watchId);
1182
+ };
1183
+ const registerMockRpc = commandMap => {
1184
+ const mockRpc = createMockRpc({
1185
+ commandMap
1186
+ });
1187
+ set$4(mockRpc);
1188
+ return mockRpc;
1244
1189
  };
1190
+
1245
1191
  const FileSystemWorker = {
1246
1192
  __proto__: null,
1247
1193
  appendFile,
1248
1194
  copy,
1249
1195
  createFile,
1250
- dispose: dispose$7,
1196
+ dispose,
1251
1197
  exists,
1252
- getFolderSize: getFolderSize$1,
1198
+ getFolderSize,
1253
1199
  getPathSeparator,
1254
1200
  getRealPath,
1255
- invoke: invoke$7,
1256
- invokeAndTransfer: invokeAndTransfer$7,
1201
+ invoke: invoke$2,
1202
+ invokeAndTransfer: invokeAndTransfer$1,
1257
1203
  mkdir,
1258
1204
  readDirWithFileTypes,
1259
1205
  readFile: readFile$1,
1260
1206
  readFileAsBlob,
1207
+ registerMockRpc,
1261
1208
  remove,
1262
1209
  rename,
1263
- set: set$7,
1210
+ set: set$4,
1264
1211
  stat,
1212
+ unwatchFile,
1213
+ watchFile,
1265
1214
  writeFile: writeFile$1
1266
1215
  };
1216
+
1267
1217
  const {
1268
- invoke: invoke$3,
1269
- invokeAndTransfer: invokeAndTransfer$3,
1270
- set: set$3$1} = create$1(RendererWorker$1);
1271
- const sendMessagePortToFileSystemWorker$2 = async (port, rpcId) => {
1218
+ invoke: invoke$1,
1219
+ invokeAndTransfer,
1220
+ set: set$3
1221
+ } = create$2(RendererWorker);
1222
+ const sendMessagePortToFileSystemWorker$1 = async (port, rpcId) => {
1272
1223
  const command = 'FileSystem.handleMessagePort';
1273
1224
  // @ts-ignore
1274
- await invokeAndTransfer$3('SendMessagePortToExtensionHostWorker.sendMessagePortToFileSystemWorker', port, command, rpcId);
1225
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToFileSystemWorker', port, command, rpcId);
1275
1226
  };
1276
- const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
1227
+ const sendMessagePortToExtensionHostWorker = async (port, rpcId = 0) => {
1277
1228
  const command = 'HandleMessagePort.handleMessagePort2';
1278
- await invokeAndTransfer$3('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
1229
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
1279
1230
  };
1280
- const activateByEvent$1 = event => {
1281
- return invoke$3('ExtensionHostManagement.activateByEvent', event);
1231
+ const activateByEvent = (event, assetDir, platform) => {
1232
+ return invoke$1('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
1233
+ };
1234
+ const showSaveFilePicker = async () => {
1235
+ // @ts-ignore
1236
+ return invoke$1('FilePicker.showSaveFilePicker');
1237
+ };
1238
+ const getLogsDir$1 = async () => {
1239
+ // @ts-ignore
1240
+ return invoke$1('PlatformPaths.getLogsDir');
1241
+ };
1242
+
1243
+ const toCommandId = key => {
1244
+ const dotIndex = key.indexOf('.');
1245
+ return key.slice(dotIndex + 1);
1246
+ };
1247
+ const create$1 = () => {
1248
+ const states = Object.create(null);
1249
+ const commandMapRef = {};
1250
+ return {
1251
+ get(uid) {
1252
+ return states[uid];
1253
+ },
1254
+ set(uid, oldState, newState) {
1255
+ states[uid] = {
1256
+ oldState,
1257
+ newState
1258
+ };
1259
+ },
1260
+ dispose(uid) {
1261
+ delete states[uid];
1262
+ },
1263
+ getKeys() {
1264
+ return Object.keys(states).map(key => {
1265
+ return Number.parseInt(key);
1266
+ });
1267
+ },
1268
+ clear() {
1269
+ for (const key of Object.keys(states)) {
1270
+ delete states[key];
1271
+ }
1272
+ },
1273
+ wrapCommand(fn) {
1274
+ const wrapped = async (uid, ...args) => {
1275
+ const {
1276
+ oldState,
1277
+ newState
1278
+ } = states[uid];
1279
+ const newerState = await fn(newState, ...args);
1280
+ if (oldState === newerState || newState === newerState) {
1281
+ return;
1282
+ }
1283
+ const latest = states[uid];
1284
+ states[uid] = {
1285
+ oldState: latest.oldState,
1286
+ newState: newerState
1287
+ };
1288
+ };
1289
+ return wrapped;
1290
+ },
1291
+ wrapGetter(fn) {
1292
+ const wrapped = (uid, ...args) => {
1293
+ const {
1294
+ newState
1295
+ } = states[uid];
1296
+ return fn(newState, ...args);
1297
+ };
1298
+ return wrapped;
1299
+ },
1300
+ diff(uid, modules, numbers) {
1301
+ const {
1302
+ oldState,
1303
+ newState
1304
+ } = states[uid];
1305
+ const diffResult = [];
1306
+ for (let i = 0; i < modules.length; i++) {
1307
+ const fn = modules[i];
1308
+ if (!fn(oldState, newState)) {
1309
+ diffResult.push(numbers[i]);
1310
+ }
1311
+ }
1312
+ return diffResult;
1313
+ },
1314
+ getCommandIds() {
1315
+ const keys = Object.keys(commandMapRef);
1316
+ const ids = keys.map(toCommandId);
1317
+ return ids;
1318
+ },
1319
+ registerCommands(commandMap) {
1320
+ Object.assign(commandMapRef, commandMap);
1321
+ }
1322
+ };
1323
+ };
1324
+ const terminate = () => {
1325
+ globalThis.close();
1282
1326
  };
1283
- const RendererWorker = {
1284
- __proto__: null,
1285
- activateByEvent: activateByEvent$1,
1286
- invoke: invoke$3,
1287
- sendMessagePortToExtensionHostWorker: sendMessagePortToExtensionHostWorker$1,
1288
- sendMessagePortToFileSystemWorker: sendMessagePortToFileSystemWorker$2,
1289
- set: set$3$1};
1290
1327
 
1291
1328
  const {
1292
- set: set$3,
1293
1329
  readFile,
1330
+ set: set$2,
1294
1331
  writeFile
1295
1332
  } = FileSystemWorker;
1296
1333
 
1334
+ const getTextFromParts = parts => {
1335
+ let result = '';
1336
+ for (const part of parts) {
1337
+ result += part.value;
1338
+ }
1339
+ return result;
1340
+ };
1297
1341
  const filterItems = (items, filterValue) => {
1298
1342
  if (!filterValue) {
1299
1343
  return items;
1300
1344
  }
1301
- return items.filter(item => item.includes(filterValue));
1345
+ return items.filter(parts => getTextFromParts(parts).includes(filterValue));
1302
1346
  };
1303
1347
 
1304
1348
  const isFileNotFoundError = error => {
1305
1349
  return error?.message?.includes('File not found') ?? false;
1306
1350
  };
1307
1351
 
1352
+ const RE_URL = /(?:https?:\/\/\S+|file:\/\/\S+)/;
1353
+ const getLinkMatch = text => {
1354
+ const match = text.match(RE_URL);
1355
+ return match ? match[0] : null;
1356
+ };
1357
+
1358
+ const Text = 1;
1359
+ const Link = 2;
1360
+
1361
+ const parseLine = line => {
1362
+ const parts = [];
1363
+ let rest = line;
1364
+ while (rest.length > 0) {
1365
+ const match = getLinkMatch(rest);
1366
+ if (!match) {
1367
+ if (rest) {
1368
+ parts.push({
1369
+ type: Text,
1370
+ value: rest
1371
+ });
1372
+ }
1373
+ break;
1374
+ }
1375
+ const index = rest.indexOf(match);
1376
+ if (index > 0) {
1377
+ parts.push({
1378
+ type: Text,
1379
+ value: rest.slice(0, index)
1380
+ });
1381
+ }
1382
+ parts.push({
1383
+ type: Link,
1384
+ value: match
1385
+ });
1386
+ rest = rest.slice(index + match.length);
1387
+ }
1388
+ if (parts.length === 0) {
1389
+ return [{
1390
+ type: Text,
1391
+ value: ''
1392
+ }];
1393
+ }
1394
+ return parts;
1395
+ };
1396
+
1308
1397
  const loadLines = async uri => {
1309
1398
  try {
1310
1399
  // TODO use log stream, updating the output when the file is changed
1311
1400
  const content = await readFile(uri);
1312
- const lines = content.split('\n');
1401
+ const lines = content.split('\n').map(parseLine);
1313
1402
  return {
1403
+ code: 0,
1314
1404
  error: '',
1315
- lines,
1316
- code: 0
1405
+ lines
1317
1406
  };
1318
1407
  } catch (error) {
1319
1408
  if (isFileNotFoundError(error)) {
1320
1409
  return {
1410
+ code: 1,
1321
1411
  error: `log file not found`,
1322
- lines: [],
1323
- code: 1
1412
+ lines: []
1324
1413
  };
1325
1414
  }
1326
1415
  return {
1416
+ code: 2,
1327
1417
  error: `${error}`,
1328
- lines: [],
1329
- code: 2
1418
+ lines: []
1330
1419
  };
1331
1420
  }
1332
1421
  };
1333
1422
 
1334
1423
  const clear = async state => {
1335
1424
  const {
1336
- selectedOption,
1425
+ filterValue,
1337
1426
  options,
1338
- filterValue
1427
+ selectedOption
1339
1428
  } = state;
1340
1429
  // TODO make uri a property of state to make the code simpler
1341
1430
  const option = options.find(option => option.id === selectedOption);
@@ -1347,17 +1436,17 @@ const clear = async state => {
1347
1436
  } = option;
1348
1437
  await writeFile(uri, '');
1349
1438
  const {
1350
- lines,
1351
1439
  code,
1352
- error
1440
+ error,
1441
+ lines
1353
1442
  } = await loadLines(uri);
1354
1443
  const filteredItems = filterItems(lines, filterValue);
1355
1444
  return {
1356
1445
  ...state,
1357
- listItems: lines,
1358
1446
  error,
1359
1447
  errorCode: code,
1360
- filteredItems
1448
+ filteredItems,
1449
+ listItems: lines
1361
1450
  };
1362
1451
  };
1363
1452
 
@@ -1373,12 +1462,13 @@ const Script = 2;
1373
1462
 
1374
1463
  const {
1375
1464
  get,
1376
- set: set$2,
1377
- wrapCommand,
1378
- wrapGetter,
1379
- getKeys,
1380
1465
  getCommandIds,
1381
- registerCommands} = create$2();
1466
+ getKeys,
1467
+ registerCommands,
1468
+ set: set$1,
1469
+ wrapCommand,
1470
+ wrapGetter
1471
+ } = create$1();
1382
1472
 
1383
1473
  const create = (id, uri, x, y, width, height, platform, parentId) => {
1384
1474
  number(parentId);
@@ -1412,7 +1502,7 @@ const create = (id, uri, x, y, width, height, platform, parentId) => {
1412
1502
  x,
1413
1503
  y
1414
1504
  };
1415
- set$2(id, state, state);
1505
+ set$1(id, state, state);
1416
1506
  };
1417
1507
 
1418
1508
  const isEqual$2 = (oldState, newState) => {
@@ -1447,8 +1537,8 @@ const diff = (oldState, newState) => {
1447
1537
 
1448
1538
  const diff2 = uid => {
1449
1539
  const {
1450
- oldState,
1451
- newState
1540
+ newState,
1541
+ oldState
1452
1542
  } = get(uid);
1453
1543
  const diffResult = diff(oldState, newState);
1454
1544
  return diffResult;
@@ -1487,52 +1577,15 @@ const focusIndex = (state, index) => {
1487
1577
  };
1488
1578
  };
1489
1579
 
1490
- const ToolBar = 'toolbar';
1491
- const AriaRoles = {
1492
- __proto__: null,
1493
- ToolBar};
1494
- const Space = 9;
1495
- const PageUp = 10;
1496
- const PageDown = 11;
1497
- const End = 255;
1498
- const Home = 12;
1499
- const LeftArrow = 13;
1500
- const UpArrow = 14;
1501
- const RightArrow = 15;
1502
- const DownArrow = 16;
1503
- const KeyCode = {
1504
- __proto__: null,
1505
- DownArrow,
1506
- End,
1507
- Home,
1508
- LeftArrow,
1509
- PageDown,
1510
- PageUp,
1511
- RightArrow,
1512
- Space,
1513
- UpArrow
1514
- };
1515
1580
  const mergeClassNames = (...classNames) => {
1516
1581
  return classNames.filter(Boolean).join(' ');
1517
1582
  };
1518
- const Button = 1;
1519
- const Div = 4;
1520
- const Input = 6;
1521
- const Text = 12;
1522
- const Select$1 = 63;
1523
- const Option$1 = 64;
1524
- const VirtualDomElements = {
1525
- __proto__: null,
1526
- Button,
1527
- Div,
1528
- Input,
1529
- Option: Option$1,
1530
- Select: Select$1};
1583
+
1531
1584
  const text = data => {
1532
1585
  return {
1533
- type: Text,
1586
+ childCount: 0,
1534
1587
  text: data,
1535
- childCount: 0
1588
+ type: Text$1
1536
1589
  };
1537
1590
  };
1538
1591
 
@@ -1540,53 +1593,53 @@ const FocusProblems = 19;
1540
1593
 
1541
1594
  const getKeyBindings = () => {
1542
1595
  return [{
1543
- key: KeyCode.DownArrow,
1544
1596
  command: 'Problems.focusNext',
1597
+ key: DownArrow,
1545
1598
  when: FocusProblems
1546
1599
  }, {
1547
- key: KeyCode.UpArrow,
1548
1600
  command: 'Problems.focusPrevious',
1601
+ key: UpArrow,
1549
1602
  when: FocusProblems
1550
1603
  }, {
1551
- key: KeyCode.Home,
1552
1604
  command: 'Problems.focusFirst',
1605
+ key: Home,
1553
1606
  when: FocusProblems
1554
1607
  }, {
1555
- key: KeyCode.PageUp,
1556
1608
  command: 'Problems.focusFirst',
1609
+ key: PageUp,
1557
1610
  when: FocusProblems
1558
1611
  }, {
1559
- key: KeyCode.PageDown,
1560
1612
  command: 'Problems.focusLast',
1613
+ key: PageDown,
1561
1614
  when: FocusProblems
1562
1615
  }, {
1563
- key: KeyCode.End,
1564
1616
  command: 'Problems.focusLast',
1617
+ key: End,
1565
1618
  when: FocusProblems
1566
1619
  }, {
1567
- key: KeyCode.Space,
1568
1620
  command: 'Problems.selectCurrent',
1621
+ key: Space,
1569
1622
  when: FocusProblems
1570
1623
  }, {
1571
- key: KeyCode.Home,
1572
1624
  command: 'Problems.focusFirst',
1625
+ key: Home,
1573
1626
  when: FocusProblems
1574
1627
  }, {
1575
- key: KeyCode.End,
1576
1628
  command: 'Problems.focusLast',
1629
+ key: End,
1577
1630
  when: FocusProblems
1578
1631
  }, {
1579
- key: KeyCode.LeftArrow,
1580
1632
  command: 'Problems.handleArrowLeft',
1633
+ key: LeftArrow,
1581
1634
  when: FocusProblems
1582
1635
  }, {
1583
- key: KeyCode.RightArrow,
1584
1636
  command: 'Problems.handleArrowRight',
1637
+ key: RightArrow,
1585
1638
  when: FocusProblems
1586
1639
  }];
1587
1640
  };
1588
1641
 
1589
- const Filter$1 = 'filter';
1642
+ const Filter$2 = 'filter';
1590
1643
  const Output$1 = 'output';
1591
1644
  const MainProcess = 'MainProcess';
1592
1645
  const SharedProcess = 'SharedProcess';
@@ -1637,8 +1690,8 @@ const handleFilterInput = async (state, value, inputSource = User) => {
1637
1690
  const filteredItems = filterItems(listItems, value);
1638
1691
  return {
1639
1692
  ...state,
1640
- filterValue: value,
1641
1693
  filteredItems: filteredItems,
1694
+ filterValue: value,
1642
1695
  inputSource
1643
1696
  };
1644
1697
  };
@@ -1648,14 +1701,6 @@ const createWatchId = () => {
1648
1701
  return watchId;
1649
1702
  };
1650
1703
 
1651
- const {
1652
- invoke: invoke$1,
1653
- sendMessagePortToExtensionHostWorker,
1654
- sendMessagePortToFileSystemWorker: sendMessagePortToFileSystemWorker$1,
1655
- set: set$1,
1656
- activateByEvent
1657
- } = RendererWorker;
1658
-
1659
1704
  const handleFileChange = async watchId => {
1660
1705
  const keys = getKeys();
1661
1706
  for (const key of keys) {
@@ -1682,14 +1727,12 @@ const setupChangeListener = async (oldWatchId, newWatchId, uri) => {
1682
1727
  try {
1683
1728
  if (oldWatchId) {
1684
1729
  unregisterWatchCallback(oldWatchId);
1685
- // @ts-ignore
1686
- await FileSystemWorker.invoke('FileSystem.unwatchFile', oldWatchId);
1730
+ await unwatchFile(oldWatchId);
1687
1731
  }
1688
1732
  // TODO dispose old watcher
1689
- const rpcId = RpcId.OutputWorker;
1733
+ const rpcId = OutputWorker;
1690
1734
  registerWatchCallback(newWatchId, handleFileChange);
1691
- // @ts-ignore
1692
- await FileSystemWorker.invoke('FileSystem.watchFile', newWatchId, /* path */uri, rpcId);
1735
+ await watchFile(newWatchId, uri, rpcId);
1693
1736
  } catch {
1694
1737
  // ignore
1695
1738
  }
@@ -1697,8 +1740,8 @@ const setupChangeListener = async (oldWatchId, newWatchId, uri) => {
1697
1740
 
1698
1741
  const selectChannel = async (state, id) => {
1699
1742
  const {
1700
- options,
1701
1743
  filterValue,
1744
+ options,
1702
1745
  watchId
1703
1746
  } = state;
1704
1747
  const matchingOption = options.find(option => option.id === id);
@@ -1707,9 +1750,9 @@ const selectChannel = async (state, id) => {
1707
1750
  }
1708
1751
  // TODO potential race condtion when switching output channels fast
1709
1752
  const {
1710
- lines,
1753
+ code,
1711
1754
  error,
1712
- code
1755
+ lines
1713
1756
  } = await loadLines(matchingOption.uri);
1714
1757
 
1715
1758
  // TODO memory leak and race condition, need to dispose file watcher of previous uri
@@ -1720,8 +1763,8 @@ const selectChannel = async (state, id) => {
1720
1763
  ...state,
1721
1764
  error,
1722
1765
  errorCode: code,
1723
- listItems: lines,
1724
1766
  filteredItems,
1767
+ listItems: lines,
1725
1768
  selectedOption: id,
1726
1769
  watchId: newWatchId
1727
1770
  };
@@ -1748,8 +1791,8 @@ const createExtensionHostRpc = async () => {
1748
1791
  };
1749
1792
 
1750
1793
  const {
1751
- set,
1752
- invoke
1794
+ invoke,
1795
+ set
1753
1796
  } = ExtensionHost;
1754
1797
 
1755
1798
  const initializeExtensionHost = async () => {
@@ -1758,7 +1801,7 @@ const initializeExtensionHost = async () => {
1758
1801
  };
1759
1802
 
1760
1803
  const sendMessagePortToFileSystemWorker = async port => {
1761
- await sendMessagePortToFileSystemWorker$1(port, RpcId.OutputWorker);
1804
+ await sendMessagePortToFileSystemWorker$1(port, OutputWorker);
1762
1805
  };
1763
1806
 
1764
1807
  const createFileSystemWorkerRpc = async () => {
@@ -1775,13 +1818,21 @@ const createFileSystemWorkerRpc = async () => {
1775
1818
 
1776
1819
  const initializeFileSystemWorker = async () => {
1777
1820
  const rpc = await createFileSystemWorkerRpc();
1778
- set$3(rpc);
1821
+ set$2(rpc);
1779
1822
  };
1780
1823
 
1781
1824
  const initialize = async () => {
1782
1825
  await Promise.all([initializeFileSystemWorker(), initializeExtensionHost()]);
1783
1826
  };
1784
1827
 
1828
+ const getLogsDir = async () => {
1829
+ try {
1830
+ return await getLogsDir$1();
1831
+ } catch {
1832
+ return `file:///tmp`;
1833
+ }
1834
+ };
1835
+
1785
1836
  const Web = 1;
1786
1837
 
1787
1838
  const getSelectedItem = (selectedOption, platform) => {
@@ -1807,6 +1858,7 @@ const i18nString = (key, placeholders = emptyObject) => {
1807
1858
  };
1808
1859
 
1809
1860
  const ClearOutput = 'clear output';
1861
+ const Filter$1 = 'Filter';
1810
1862
  const LogFileNotFound$1 = 'The log file was not found.';
1811
1863
  const Settings = 'Settings';
1812
1864
  const TurnOffAutoScroll = 'Turn auto scrolling off';
@@ -1823,20 +1875,23 @@ const settings = () => {
1823
1875
  const logFileNotFound = () => {
1824
1876
  return i18nString(LogFileNotFound$1);
1825
1877
  };
1878
+ const filter = () => {
1879
+ return i18nString(Filter$1);
1880
+ };
1826
1881
 
1827
1882
  const loadButtons = () => {
1828
1883
  return [{
1884
+ icon: 'MaskIconClearAll',
1829
1885
  id: Clear,
1830
- label: clearOutput(),
1831
- icon: 'MaskIconClearAll'
1886
+ label: clearOutput()
1832
1887
  }, {
1888
+ icon: 'MaskIconListFlat',
1833
1889
  id: ScrollLock,
1834
- label: turnOffAutoScroll(),
1835
- icon: 'MaskIconListFlat'
1890
+ label: turnOffAutoScroll()
1836
1891
  }, {
1892
+ icon: 'MaskIconSettingsGear',
1837
1893
  id: Settings$1,
1838
- label: settings(),
1839
- icon: 'MaskIconSettingsGear'
1894
+ label: settings()
1840
1895
  }];
1841
1896
  };
1842
1897
 
@@ -1849,6 +1904,7 @@ const getExtensionOptions = async () => {
1849
1904
  // TODO make api more declarative:
1850
1905
  // output channels are registered in extension manifest
1851
1906
  // only downside: it might show channels for extensions that are not active
1907
+ // @ts-ignore
1852
1908
  await activateByEvent('onOutput');
1853
1909
  // @ts-ignore
1854
1910
  const channels = await invoke('Output.getEnabledProviders');
@@ -1859,7 +1915,7 @@ const getExtensionOptions = async () => {
1859
1915
  }
1860
1916
  };
1861
1917
 
1862
- const loadOptions = async platform => {
1918
+ const loadOptions = async (platform, logsFolderPath) => {
1863
1919
  const extensionOptions = await getExtensionOptions();
1864
1920
  if (platform === Web) {
1865
1921
  return extensionOptions;
@@ -1867,11 +1923,11 @@ const loadOptions = async platform => {
1867
1923
  return [{
1868
1924
  id: MainProcess,
1869
1925
  label: 'Main Process',
1870
- uri: 'file:///tmp/log-main-process.txt'
1926
+ uri: `${logsFolderPath}/log-main-process.txt`
1871
1927
  }, {
1872
1928
  id: SharedProcess,
1873
1929
  label: 'Shared Process',
1874
- uri: 'file:///tmp/log-shared-process.txt'
1930
+ uri: `${logsFolderPath}/log-shared-process.txt`
1875
1931
  }, ...extensionOptions];
1876
1932
  };
1877
1933
 
@@ -1899,8 +1955,8 @@ const restoreState = savedState => {
1899
1955
  const scrollLockEnabled = getSavedScrollLockEnabled(savedState);
1900
1956
  return {
1901
1957
  filterValue,
1902
- selectedOption,
1903
- scrollLockEnabled
1958
+ scrollLockEnabled,
1959
+ selectedOption
1904
1960
  };
1905
1961
  };
1906
1962
 
@@ -1922,13 +1978,14 @@ const loadContent = async (state, savedState) => {
1922
1978
  watchId
1923
1979
  } = state;
1924
1980
  const collapsedUris = getSavedCollapsedUris(savedState);
1981
+ const logsFolderPath = await getLogsDir();
1925
1982
  const {
1926
- selectedOption,
1927
1983
  filterValue,
1928
- scrollLockEnabled
1984
+ scrollLockEnabled,
1985
+ selectedOption
1929
1986
  } = restoreState(savedState);
1930
1987
  const selectedId = getSelectedItem(selectedOption, platform);
1931
- const options = await loadOptions(platform);
1988
+ const options = await loadOptions(platform, logsFolderPath);
1932
1989
  const option = getMatchingOpen(options, selectedId);
1933
1990
  if (!option) {
1934
1991
  throw new Error('option not found');
@@ -1937,9 +1994,9 @@ const loadContent = async (state, savedState) => {
1937
1994
  uri
1938
1995
  } = option;
1939
1996
  const {
1940
- lines,
1997
+ code,
1941
1998
  error,
1942
- code
1999
+ lines
1943
2000
  } = await loadLines(uri);
1944
2001
  const filteredItems = filterItems(lines, filterValue);
1945
2002
  const newWatchId = createWatchId();
@@ -1984,22 +2041,22 @@ const refresh = async state => {
1984
2041
  return state;
1985
2042
  }
1986
2043
  const {
1987
- lines,
2044
+ code,
1988
2045
  error,
1989
- code
2046
+ lines
1990
2047
  } = await loadLines(matchingOption.uri);
1991
2048
  const filteredItems = filterItems(lines, filterValue);
1992
2049
  return {
1993
2050
  ...state,
1994
- listItems: lines,
1995
- filteredItems,
1996
2051
  error,
1997
- errorCode: code
2052
+ errorCode: code,
2053
+ filteredItems,
2054
+ listItems: lines
1998
2055
  };
1999
2056
  };
2000
2057
 
2001
2058
  const renderFilterValue = (oldState, newState) => {
2002
- return ['Viewlet.setValueByName', newState.parentId, Filter$1, newState.filterValue];
2059
+ return ['Viewlet.setValueByName', newState.parentId, Filter$2, newState.filterValue];
2003
2060
  };
2004
2061
 
2005
2062
  const Filter = 'Filter';
@@ -2018,12 +2075,30 @@ const Error$1 = 'Error';
2018
2075
  const Line = 'Line';
2019
2076
 
2020
2077
  const parentNode = {
2021
- type: VirtualDomElements.Div,
2078
+ childCount: 1,
2022
2079
  className: Line,
2023
- childCount: 1
2080
+ type: Div
2024
2081
  };
2025
- const getLineDom = line => {
2026
- return [parentNode, text(line)];
2082
+ const getLineDom = parts => {
2083
+ const children = [];
2084
+ for (const part of parts) {
2085
+ if (part.type === Text) {
2086
+ children.push(text(part.value));
2087
+ } else {
2088
+ children.push({
2089
+ childCount: 1,
2090
+ href: part.value,
2091
+ rel: 'noopener noreferrer',
2092
+ target: '_blank',
2093
+ type: A
2094
+ }, text(part.value));
2095
+ }
2096
+ }
2097
+ const lineNode = {
2098
+ ...parentNode,
2099
+ childCount: children.length
2100
+ };
2101
+ return [lineNode, ...children];
2027
2102
  };
2028
2103
 
2029
2104
  const getContentDom = (lines, error) => {
@@ -2031,11 +2106,11 @@ const getContentDom = (lines, error) => {
2031
2106
  return [];
2032
2107
  }
2033
2108
  return [{
2034
- type: VirtualDomElements.Div,
2109
+ childCount: lines.length,
2035
2110
  className: OutputContent,
2036
2111
  role: 'log',
2037
2112
  tabIndex: 0,
2038
- childCount: lines.length
2113
+ type: Div
2039
2114
  }, ...lines.flatMap(getLineDom)];
2040
2115
  };
2041
2116
 
@@ -2043,10 +2118,10 @@ const LogFileNotFound = 1;
2043
2118
 
2044
2119
  const getLogFileNotFoundDom = () => {
2045
2120
  return [{
2046
- type: VirtualDomElements.Div,
2121
+ childCount: 1,
2047
2122
  className: Message,
2048
2123
  tabIndex: 0,
2049
- childCount: 1
2124
+ type: Div
2050
2125
  }, text(logFileNotFound())];
2051
2126
  };
2052
2127
 
@@ -2058,18 +2133,18 @@ const getErrorDom = (errorCode, error) => {
2058
2133
  return getLogFileNotFoundDom();
2059
2134
  }
2060
2135
  return [{
2061
- type: VirtualDomElements.Div,
2136
+ childCount: 1,
2062
2137
  className: Error$1,
2063
2138
  tabIndex: 0,
2064
- childCount: 1
2139
+ type: Div
2065
2140
  }, text(error)];
2066
2141
  };
2067
2142
 
2068
2143
  const getOutputVirtualDom = (lines, errorCode, error) => {
2069
2144
  return [{
2070
- type: VirtualDomElements.Div,
2145
+ childCount: 1,
2071
2146
  className: mergeClassNames(Viewlet, Output),
2072
- childCount: 1
2147
+ type: Div
2073
2148
  }, ...getContentDom(lines, error), ...getErrorDom(errorCode, error)];
2074
2149
  };
2075
2150
 
@@ -2086,10 +2161,10 @@ const renderSelectedItem = (oldState, newState) => {
2086
2161
 
2087
2162
  const getRenderer = diffType => {
2088
2163
  switch (diffType) {
2089
- case RenderItems:
2090
- return renderItems;
2091
2164
  case RenderFilterValue:
2092
2165
  return renderFilterValue;
2166
+ case RenderItems:
2167
+ return renderItems;
2093
2168
  case RenderSelectedItem:
2094
2169
  return renderSelectedItem;
2095
2170
  default:
@@ -2108,10 +2183,10 @@ const applyRender = (oldState, newState, diffResult) => {
2108
2183
 
2109
2184
  const render2 = (uid, diffResult) => {
2110
2185
  const {
2111
- oldState,
2112
- newState
2186
+ newState,
2187
+ oldState
2113
2188
  } = get(uid);
2114
- set$2(uid, newState, newState);
2189
+ set$1(uid, newState, newState);
2115
2190
  const commands = applyRender(oldState, newState, diffResult);
2116
2191
  return commands;
2117
2192
  };
@@ -2126,20 +2201,20 @@ const HandleButtonClick = 'handleButtonClick';
2126
2201
 
2127
2202
  const getActionButtonVirtualDom = button => {
2128
2203
  const {
2204
+ icon,
2129
2205
  id,
2130
- label,
2131
- icon
2206
+ label
2132
2207
  } = button;
2133
2208
  return [{
2134
- type: VirtualDomElements.Button,
2209
+ childCount: 1,
2135
2210
  className: IconButton,
2136
2211
  name: id,
2212
+ onClick: HandleButtonClick,
2137
2213
  title: label,
2138
- childCount: 1,
2139
- onClick: HandleButtonClick
2214
+ type: Button
2140
2215
  }, {
2141
- type: VirtualDomElements.Div,
2142
- className: mergeClassNames(MaskIcon, icon)
2216
+ className: mergeClassNames(MaskIcon, icon),
2217
+ type: Div
2143
2218
  }];
2144
2219
  };
2145
2220
 
@@ -2148,18 +2223,18 @@ const getActionButtonsVirtualDom = buttons => {
2148
2223
  };
2149
2224
 
2150
2225
  const getFilterVirtualDom = () => {
2151
- const placeholder = 'Filter';
2226
+ const placeholder = filter();
2152
2227
  return [{
2153
- type: VirtualDomElements.Div,
2228
+ childCount: 1,
2154
2229
  className: Filter,
2155
- childCount: 1
2230
+ type: Div
2156
2231
  }, {
2157
- type: VirtualDomElements.Input,
2158
- className: mergeClassNames(InputBox, FilterInput),
2159
2232
  childCount: 0,
2160
- placeholder,
2233
+ className: mergeClassNames(InputBox, FilterInput),
2234
+ name: Filter$2,
2161
2235
  onInput: HandleFilterInput,
2162
- name: Filter$1
2236
+ placeholder,
2237
+ type: Input
2163
2238
  }];
2164
2239
  };
2165
2240
 
@@ -2169,20 +2244,20 @@ const getOptionVirtualDom = option => {
2169
2244
  label
2170
2245
  } = option;
2171
2246
  return [{
2172
- type: VirtualDomElements.Option,
2173
- className: Option,
2174
2247
  childCount: 1,
2248
+ className: Option,
2249
+ type: Option$1,
2175
2250
  value: id
2176
2251
  }, text(label)];
2177
2252
  };
2178
2253
 
2179
2254
  const getSelectVirtualDom = options => {
2180
2255
  return [{
2181
- type: VirtualDomElements.Select,
2182
- className: Select,
2183
2256
  childCount: options.length,
2257
+ className: Select,
2184
2258
  name: Output$1,
2185
- onChange: HandleSelect
2259
+ onChange: HandleSelect,
2260
+ type: Select$1
2186
2261
  }, ...options.flatMap(getOptionVirtualDom)];
2187
2262
  };
2188
2263
 
@@ -2194,17 +2269,17 @@ const getChildCount = buttonsLength => {
2194
2269
  const getActionsVirtualDom = (options, buttons) => {
2195
2270
  const childCount = getChildCount(buttons.length);
2196
2271
  return [{
2197
- type: VirtualDomElements.Div,
2272
+ childCount,
2198
2273
  className: Actions,
2199
- role: AriaRoles.ToolBar,
2200
- childCount
2274
+ role: ToolBar,
2275
+ type: Div
2201
2276
  }, ...getFilterVirtualDom(), ...getSelectVirtualDom(options), ...getActionButtonsVirtualDom(buttons)];
2202
2277
  };
2203
2278
 
2204
2279
  const renderActions = state => {
2205
2280
  const {
2206
- options,
2207
- buttons
2281
+ buttons,
2282
+ options
2208
2283
  } = state;
2209
2284
  const dom = getActionsVirtualDom(options, buttons);
2210
2285
  return dom;
@@ -2244,25 +2319,42 @@ const resize = (state, dimensions) => {
2244
2319
  };
2245
2320
  };
2246
2321
 
2322
+ const serializeLinePart = part => {
2323
+ return part.value;
2324
+ };
2325
+ const serializeLineParts = parts => {
2326
+ return parts.map(serializeLinePart).join('');
2327
+ };
2328
+ const serializeLines = lines => {
2329
+ return lines.map(serializeLineParts).join('\n');
2330
+ };
2331
+
2247
2332
  const saveOutputAs = async state => {
2248
- // TODO show open file picker
2249
- // TODO write to file
2333
+ const uri = await showSaveFilePicker();
2334
+ if (!uri) {
2335
+ return state;
2336
+ }
2337
+ const {
2338
+ listItems
2339
+ } = state;
2340
+ const content = serializeLines(listItems);
2341
+ await writeFile(uri, content);
2250
2342
  // TODO if error occurs, show error dialog
2251
2343
  return state;
2252
2344
  };
2253
2345
 
2254
2346
  const saveState = state => {
2255
2347
  const {
2256
- filterValue,
2257
2348
  collapsedUris,
2258
- selectedOption,
2259
- scrollLockEnabled
2349
+ filterValue,
2350
+ scrollLockEnabled,
2351
+ selectedOption
2260
2352
  } = state;
2261
2353
  return {
2262
- filterValue,
2263
2354
  collapsedUris,
2264
- selectedOption,
2265
- scrollLockEnabled
2355
+ filterValue,
2356
+ scrollLockEnabled,
2357
+ selectedOption
2266
2358
  };
2267
2359
  };
2268
2360
 
@@ -2306,7 +2398,7 @@ const commandMap = {
2306
2398
  'Output.renderActions': wrapGetter(renderActions),
2307
2399
  'Output.renderEventListeners': renderEventListeners,
2308
2400
  'Output.resize': resize,
2309
- 'Output.saveOutputAs': wrapCommand(saveOutputAs),
2401
+ 'Output.saveAs': wrapCommand(saveOutputAs),
2310
2402
  'Output.saveState': wrapGetter(saveState),
2311
2403
  'Output.selectChannel': wrapCommand(selectChannel),
2312
2404
  'Output.setLogLevel': setLogLevel,
@@ -2322,7 +2414,7 @@ const listen = async () => {
2322
2414
  const rpc = await WebWorkerRpcClient.create({
2323
2415
  commandMap: commandMapRef
2324
2416
  });
2325
- set$1(rpc);
2417
+ set$3(rpc);
2326
2418
  };
2327
2419
 
2328
2420
  const main = async () => {