@lvce-editor/source-control-worker 2.23.0 → 3.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.
@@ -456,7 +456,7 @@ const getFirstEvent = (eventEmitter, eventMap) => {
456
456
  return promise;
457
457
  };
458
458
  const Message$1 = 3;
459
- const create$5$1 = async ({
459
+ const create$5 = async ({
460
460
  isMessagePortOpen,
461
461
  messagePort
462
462
  }) => {
@@ -507,61 +507,19 @@ const wrap$5 = messagePort => {
507
507
  };
508
508
  const IpcParentWithMessagePort$1 = {
509
509
  __proto__: null,
510
- create: create$5$1,
510
+ create: create$5,
511
511
  signal: signal$1,
512
512
  wrap: wrap$5
513
513
  };
514
514
 
515
- const Two = '2.0';
516
- const create$4 = (method, params) => {
517
- return {
518
- jsonrpc: Two,
519
- method,
520
- params
521
- };
522
- };
515
+ const Two$1 = '2.0';
523
516
  const callbacks = Object.create(null);
524
- const set$5 = (id, fn) => {
525
- callbacks[id] = fn;
526
- };
527
517
  const get$3 = id => {
528
518
  return callbacks[id];
529
519
  };
530
- const remove = id => {
520
+ const remove$1 = id => {
531
521
  delete callbacks[id];
532
522
  };
533
- let id = 0;
534
- const create$3$1 = () => {
535
- return ++id;
536
- };
537
- const registerPromise = () => {
538
- const id = create$3$1();
539
- const {
540
- resolve,
541
- promise
542
- } = Promise.withResolvers();
543
- set$5(id, resolve);
544
- return {
545
- id,
546
- promise
547
- };
548
- };
549
- const create$2$1 = (method, params) => {
550
- const {
551
- id,
552
- promise
553
- } = registerPromise();
554
- const message = {
555
- jsonrpc: Two,
556
- method,
557
- params,
558
- id
559
- };
560
- return {
561
- message,
562
- promise
563
- };
564
- };
565
523
  class JsonRpcError extends Error {
566
524
  constructor(message) {
567
525
  super(message);
@@ -712,7 +670,7 @@ const resolve = (id, response) => {
712
670
  return;
713
671
  }
714
672
  fn(response);
715
- remove(id);
673
+ remove$1(id);
716
674
  };
717
675
  const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
718
676
  const getErrorType = prettyError => {
@@ -755,9 +713,9 @@ const getErrorProperty = (error, prettyError) => {
755
713
  }
756
714
  };
757
715
  };
758
- const create$1$1 = (id, error) => {
716
+ const create$1$2 = (id, error) => {
759
717
  return {
760
- jsonrpc: Two,
718
+ jsonrpc: Two$1,
761
719
  id,
762
720
  error
763
721
  };
@@ -766,22 +724,22 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
766
724
  const prettyError = preparePrettyError(error);
767
725
  logError(error, prettyError);
768
726
  const errorProperty = getErrorProperty(error, prettyError);
769
- return create$1$1(id, errorProperty);
727
+ return create$1$2(id, errorProperty);
770
728
  };
771
- const create$6 = (message, result) => {
729
+ const create$3 = (message, result) => {
772
730
  return {
773
- jsonrpc: Two,
731
+ jsonrpc: Two$1,
774
732
  id: message.id,
775
733
  result: result ?? null
776
734
  };
777
735
  };
778
736
  const getSuccessResponse = (message, result) => {
779
737
  const resultProperty = result ?? null;
780
- return create$6(message, resultProperty);
738
+ return create$3(message, resultProperty);
781
739
  };
782
740
  const getErrorResponseSimple = (id, error) => {
783
741
  return {
784
- jsonrpc: Two,
742
+ jsonrpc: Two$1,
785
743
  id,
786
744
  error: {
787
745
  code: Custom,
@@ -868,29 +826,6 @@ const handleJsonRpcMessage = async (...args) => {
868
826
  }
869
827
  throw new JsonRpcError('unexpected message');
870
828
  };
871
- const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
872
- const {
873
- message,
874
- promise
875
- } = create$2$1(method, params);
876
- if (useSendAndTransfer && ipc.sendAndTransfer) {
877
- ipc.sendAndTransfer(message);
878
- } else {
879
- ipc.send(message);
880
- }
881
- const responseMessage = await promise;
882
- return unwrapJsonRpcResult(responseMessage);
883
- };
884
- const send = (transport, method, ...params) => {
885
- const message = create$4(method, params);
886
- transport.send(message);
887
- };
888
- const invoke$2 = (ipc, method, ...params) => {
889
- return invokeHelper(ipc, method, params, false);
890
- };
891
- const invokeAndTransfer$1 = (ipc, method, ...params) => {
892
- return invokeHelper(ipc, method, params, true);
893
- };
894
829
 
895
830
  class CommandNotFoundError extends Error {
896
831
  constructor(command) {
@@ -913,24 +848,87 @@ const execute = (command, ...args) => {
913
848
  return fn(...args);
914
849
  };
915
850
 
851
+ const Two = '2.0';
852
+ const create$s = (method, params) => {
853
+ return {
854
+ jsonrpc: Two,
855
+ method,
856
+ params
857
+ };
858
+ };
859
+ const create$r = (id, method, params) => {
860
+ const message = {
861
+ id,
862
+ jsonrpc: Two,
863
+ method,
864
+ params
865
+ };
866
+ return message;
867
+ };
868
+ let id = 0;
869
+ const create$q = () => {
870
+ return ++id;
871
+ };
872
+
873
+ /* eslint-disable n/no-unsupported-features/es-syntax */
874
+
875
+ const registerPromise = map => {
876
+ const id = create$q();
877
+ const {
878
+ promise,
879
+ resolve
880
+ } = Promise.withResolvers();
881
+ map[id] = resolve;
882
+ return {
883
+ id,
884
+ promise
885
+ };
886
+ };
887
+
888
+ // @ts-ignore
889
+ const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer) => {
890
+ const {
891
+ id,
892
+ promise
893
+ } = registerPromise(callbacks);
894
+ const message = create$r(id, method, params);
895
+ if (useSendAndTransfer && ipc.sendAndTransfer) {
896
+ ipc.sendAndTransfer(message);
897
+ } else {
898
+ ipc.send(message);
899
+ }
900
+ const responseMessage = await promise;
901
+ return unwrapJsonRpcResult(responseMessage);
902
+ };
916
903
  const createRpc = ipc => {
904
+ const callbacks = Object.create(null);
905
+ ipc._resolve = (id, response) => {
906
+ const fn = callbacks[id];
907
+ if (!fn) {
908
+ console.warn(`callback ${id} may already be disposed`);
909
+ return;
910
+ }
911
+ fn(response);
912
+ delete callbacks[id];
913
+ };
917
914
  const rpc = {
915
+ async dispose() {
916
+ await ipc?.dispose();
917
+ },
918
+ invoke(method, ...params) {
919
+ return invokeHelper(callbacks, ipc, method, params, false);
920
+ },
921
+ invokeAndTransfer(method, ...params) {
922
+ return invokeHelper(callbacks, ipc, method, params, true);
923
+ },
918
924
  // @ts-ignore
919
925
  ipc,
920
926
  /**
921
927
  * @deprecated
922
928
  */
923
929
  send(method, ...params) {
924
- send(ipc, method, ...params);
925
- },
926
- invoke(method, ...params) {
927
- return invoke$2(ipc, method, ...params);
928
- },
929
- invokeAndTransfer(method, ...params) {
930
- return invokeAndTransfer$1(ipc, method, ...params);
931
- },
932
- async dispose() {
933
- await ipc?.dispose();
930
+ const message = create$s(method, params);
931
+ ipc.send(message);
934
932
  }
935
933
  };
936
934
  return rpc;
@@ -947,7 +945,7 @@ const logError = () => {
947
945
  const handleMessage = event => {
948
946
  const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
949
947
  const actualExecute = event?.target?.execute || execute;
950
- return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
948
+ return handleJsonRpcMessage(event.target, event.data, actualExecute, event.target._resolve, preparePrettyError, logError, actualRequiresSocket);
951
949
  };
952
950
  const handleIpc = ipc => {
953
951
  if ('addEventListener' in ipc) {
@@ -965,15 +963,16 @@ const listen$1 = async (module, options) => {
965
963
  const ipc = module.wrap(rawIpc);
966
964
  return ipc;
967
965
  };
968
- const create$5 = async ({
966
+ const create$4 = async ({
969
967
  commandMap,
968
+ isMessagePortOpen = true,
970
969
  messagePort
971
970
  }) => {
972
971
  // TODO create a commandMap per rpc instance
973
972
  register(commandMap);
974
973
  const rawIpc = await IpcParentWithMessagePort$1.create({
975
- messagePort,
976
- isMessagePortOpen: true
974
+ isMessagePortOpen,
975
+ messagePort
977
976
  });
978
977
  const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
979
978
  handleIpc(ipc);
@@ -983,10 +982,11 @@ const create$5 = async ({
983
982
  };
984
983
  const PlainMessagePortRpc = {
985
984
  __proto__: null,
986
- create: create$5
985
+ create: create$4
987
986
  };
988
- const create$3 = async ({
987
+ const create$2 = async ({
989
988
  commandMap,
989
+ isMessagePortOpen,
990
990
  send
991
991
  }) => {
992
992
  const {
@@ -994,16 +994,17 @@ const create$3 = async ({
994
994
  port2
995
995
  } = new MessageChannel();
996
996
  await send(port1);
997
- return create$5({
997
+ return create$4({
998
998
  commandMap,
999
+ isMessagePortOpen,
999
1000
  messagePort: port2
1000
1001
  });
1001
1002
  };
1002
1003
  const TransferMessagePortRpcParent = {
1003
1004
  __proto__: null,
1004
- create: create$3
1005
+ create: create$2
1005
1006
  };
1006
- const create$2 = async ({
1007
+ const create$1$1 = async ({
1007
1008
  commandMap
1008
1009
  }) => {
1009
1010
  // TODO create a commandMap per rpc instance
@@ -1015,14 +1016,48 @@ const create$2 = async ({
1015
1016
  };
1016
1017
  const WebWorkerRpcClient = {
1017
1018
  __proto__: null,
1018
- create: create$2
1019
+ create: create$1$1
1019
1020
  };
1021
+ const createMockRpc = ({
1022
+ commandMap
1023
+ }) => {
1024
+ const invocations = [];
1025
+ const invoke = (method, ...params) => {
1026
+ invocations.push([method, ...params]);
1027
+ const command = commandMap[method];
1028
+ if (!command) {
1029
+ throw new Error(`command ${method} not found`);
1030
+ }
1031
+ return command(...params);
1032
+ };
1033
+ const mockRpc = {
1034
+ invocations,
1035
+ invoke,
1036
+ invokeAndTransfer: invoke
1037
+ };
1038
+ return mockRpc;
1039
+ };
1040
+
1041
+ const None$1 = 'none';
1042
+ const ToolBar = 'toolbar';
1043
+ const Tree$1 = 'tree';
1044
+ const TreeItem$1 = 'treeitem';
1045
+
1046
+ const Badge = 'Badge';
1047
+ const SourceControlBadge = 'SourceControlBadge';
1020
1048
 
1021
1049
  const Directory = 3;
1022
1050
  const DirectoryExpanded = 4;
1023
1051
  const File = 7;
1024
1052
 
1025
- const Button$2 = 'event.button';
1053
+ const Button$2 = 1;
1054
+ const Div = 4;
1055
+ const Span = 8;
1056
+ const Text = 12;
1057
+ const Img = 17;
1058
+ const TextArea = 62;
1059
+
1060
+ const Button$1 = 'event.button';
1026
1061
  const ClientX = 'event.clientX';
1027
1062
  const ClientY = 'event.clientY';
1028
1063
  const DeltaMode = 'event.deltaMode';
@@ -1030,14 +1065,19 @@ const DeltaY = 'event.deltaY';
1030
1065
  const TargetName = 'event.target.name';
1031
1066
  const TargetValue = 'event.target.value';
1032
1067
 
1068
+ const Enter = 3;
1069
+
1033
1070
  const User = 1;
1034
1071
  const Script = 2;
1035
1072
 
1073
+ const CtrlCmd = 1 << 11 >>> 0;
1074
+
1036
1075
  const SourceControl$1 = 22;
1037
1076
 
1038
- const None$1 = 0;
1077
+ const None = 0;
1039
1078
 
1040
1079
  const ExtensionHostWorker = 44;
1080
+ const ExtensionManagementWorker = 9006;
1041
1081
  const IconThemeWorker = 7009;
1042
1082
  const RendererWorker = 1;
1043
1083
  const SourceControlWorker = 66;
@@ -1048,18 +1088,22 @@ const SetFocusContext = 'Viewlet.setFocusContext';
1048
1088
  const SetValueByName = 'Viewlet.setValueByName';
1049
1089
 
1050
1090
  const List = 1;
1051
- const Tree$1 = 2;
1091
+ const Tree = 2;
1052
1092
 
1053
1093
  const FocusSourceControlInput = 24;
1054
1094
 
1055
1095
  const rpcs = Object.create(null);
1056
- const set$4 = (id, rpc) => {
1096
+ const set$5 = (id, rpc) => {
1057
1097
  rpcs[id] = rpc;
1058
1098
  };
1059
1099
  const get$2 = id => {
1060
1100
  return rpcs[id];
1061
1101
  };
1102
+ const remove = id => {
1103
+ delete rpcs[id];
1104
+ };
1062
1105
 
1106
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
1063
1107
  const create$1 = rpcId => {
1064
1108
  return {
1065
1109
  async dispose() {
@@ -1078,17 +1122,33 @@ const create$1 = rpcId => {
1078
1122
  // @ts-ignore
1079
1123
  return rpc.invokeAndTransfer(method, ...params);
1080
1124
  },
1125
+ registerMockRpc(commandMap) {
1126
+ const mockRpc = createMockRpc({
1127
+ commandMap
1128
+ });
1129
+ set$5(rpcId, mockRpc);
1130
+ // @ts-ignore
1131
+ mockRpc[Symbol.dispose] = () => {
1132
+ remove(rpcId);
1133
+ };
1134
+ // @ts-ignore
1135
+ return mockRpc;
1136
+ },
1081
1137
  set(rpc) {
1082
- set$4(rpcId, rpc);
1138
+ set$5(rpcId, rpc);
1083
1139
  }
1084
1140
  };
1085
1141
  };
1086
1142
 
1087
1143
  const {
1088
1144
  invoke: invoke$1,
1089
- set: set$3
1145
+ set: set$4
1090
1146
  } = create$1(ExtensionHostWorker);
1091
1147
 
1148
+ const {
1149
+ set: set$3
1150
+ } = create$1(ExtensionManagementWorker);
1151
+
1092
1152
  const {
1093
1153
  invoke,
1094
1154
  invokeAndTransfer,
@@ -1117,6 +1177,10 @@ const sendMessagePortToTextMeasurementWorker$1 = async port => {
1117
1177
  // @ts-ignore
1118
1178
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToTextMeasurementWorker', port, command, 0);
1119
1179
  };
1180
+ const sendMessagePortToExtensionManagementWorker = async (port, rpcId) => {
1181
+ const command = 'Extensions.handleMessagePort';
1182
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionManagementWorker', port, command, rpcId);
1183
+ };
1120
1184
  const getPreference = async key => {
1121
1185
  return await invoke('Preferences.get', key);
1122
1186
  };
@@ -1761,6 +1825,7 @@ const loadContent = async (state, savedState) => {
1761
1825
  finalDeltaY,
1762
1826
  gitRoot,
1763
1827
  iconDefinitions,
1828
+ initial: false,
1764
1829
  inputBoxHeight,
1765
1830
  inputPlaceholder,
1766
1831
  inputValue,
@@ -1834,6 +1899,7 @@ const create2 = (id, uri, x, y, width, height, workspacePath, platform, assetDir
1834
1899
  iconDefinitions: [],
1835
1900
  id,
1836
1901
  index: [],
1902
+ initial: true,
1837
1903
  inputBoxHeight: 30,
1838
1904
  inputBoxMaxHeight: 214,
1839
1905
  inputFontFamily: 'system-ui, Ubuntu, "Droid Sans", sans-serif',
@@ -1887,13 +1953,14 @@ const RenderItems = 4;
1887
1953
  const RenderFocusContext = 7;
1888
1954
  const RenderValue = 8;
1889
1955
  const RenderCss = 10;
1956
+ const RenderIncremental = 11;
1890
1957
 
1891
1958
  const isEqual = (oldState, newState) => {
1892
1959
  return newState.inputSource === User || oldState.inputValue === newState.inputValue;
1893
1960
  };
1894
1961
 
1895
1962
  const modules = [isEqual$1, isEqual, isEqual$3, isEqual$2];
1896
- const numbers = [RenderItems, RenderValue, RenderCss, RenderFocusContext];
1963
+ const numbers = [RenderIncremental, RenderValue, RenderCss, RenderFocusContext];
1897
1964
 
1898
1965
  const diff = (oldState, newState) => {
1899
1966
  const diffResult = [];
@@ -1928,37 +1995,295 @@ const getInfo = uid => {
1928
1995
  return newState.allGroups;
1929
1996
  };
1930
1997
 
1931
- const None = 'none';
1932
- const ToolBar = 'toolbar';
1933
- const Tree = 'tree';
1934
- const TreeItem$1 = 'treeitem';
1935
-
1936
- const Badge = 'Badge';
1937
- const SourceControlBadge = 'SourceControlBadge';
1938
-
1939
- const Button$1 = 1;
1940
- const Div = 4;
1941
- const Span = 8;
1942
- const Text = 12;
1943
- const Img = 17;
1944
- const TextArea = 62;
1945
-
1946
- const Enter = 3;
1947
-
1948
- const CtrlCmd = 1 << 11 >>> 0;
1949
-
1950
1998
  const mergeClassNames = (...classNames) => {
1951
1999
  return classNames.filter(Boolean).join(' ');
1952
2000
  };
1953
2001
 
1954
2002
  const text = data => {
1955
2003
  return {
1956
- type: Text,
2004
+ childCount: 0,
1957
2005
  text: data,
1958
- childCount: 0
2006
+ type: Text
1959
2007
  };
1960
2008
  };
1961
2009
 
2010
+ const SetText = 1;
2011
+ const Replace = 2;
2012
+ const SetAttribute = 3;
2013
+ const RemoveAttribute = 4;
2014
+ const Add = 6;
2015
+ const NavigateChild = 7;
2016
+ const NavigateParent = 8;
2017
+ const RemoveChild = 9;
2018
+ const NavigateSibling = 10;
2019
+
2020
+ const isKey = key => {
2021
+ return key !== 'type' && key !== 'childCount';
2022
+ };
2023
+
2024
+ const getKeys = node => {
2025
+ const keys = Object.keys(node).filter(isKey);
2026
+ return keys;
2027
+ };
2028
+
2029
+ const arrayToTree = nodes => {
2030
+ const result = [];
2031
+ let i = 0;
2032
+ while (i < nodes.length) {
2033
+ const node = nodes[i];
2034
+ const {
2035
+ children,
2036
+ nodesConsumed
2037
+ } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
2038
+ result.push({
2039
+ node,
2040
+ children
2041
+ });
2042
+ i += 1 + nodesConsumed;
2043
+ }
2044
+ return result;
2045
+ };
2046
+ const getChildrenWithCount = (nodes, startIndex, childCount) => {
2047
+ if (childCount === 0) {
2048
+ return {
2049
+ children: [],
2050
+ nodesConsumed: 0
2051
+ };
2052
+ }
2053
+ const children = [];
2054
+ let i = startIndex;
2055
+ let remaining = childCount;
2056
+ let totalConsumed = 0;
2057
+ while (remaining > 0 && i < nodes.length) {
2058
+ const node = nodes[i];
2059
+ const nodeChildCount = node.childCount || 0;
2060
+ const {
2061
+ children: nodeChildren,
2062
+ nodesConsumed
2063
+ } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
2064
+ children.push({
2065
+ node,
2066
+ children: nodeChildren
2067
+ });
2068
+ const nodeSize = 1 + nodesConsumed;
2069
+ i += nodeSize;
2070
+ totalConsumed += nodeSize;
2071
+ remaining--;
2072
+ }
2073
+ return {
2074
+ children,
2075
+ nodesConsumed: totalConsumed
2076
+ };
2077
+ };
2078
+
2079
+ const compareNodes = (oldNode, newNode) => {
2080
+ const patches = [];
2081
+ // Check if node type changed - return null to signal incompatible nodes
2082
+ // (caller should handle this with a Replace operation)
2083
+ if (oldNode.type !== newNode.type) {
2084
+ return null;
2085
+ }
2086
+ // Handle text nodes
2087
+ if (oldNode.type === Text && newNode.type === Text) {
2088
+ if (oldNode.text !== newNode.text) {
2089
+ patches.push({
2090
+ type: SetText,
2091
+ value: newNode.text
2092
+ });
2093
+ }
2094
+ return patches;
2095
+ }
2096
+ // Compare attributes
2097
+ const oldKeys = getKeys(oldNode);
2098
+ const newKeys = getKeys(newNode);
2099
+ // Check for attribute changes
2100
+ for (const key of newKeys) {
2101
+ if (oldNode[key] !== newNode[key]) {
2102
+ patches.push({
2103
+ type: SetAttribute,
2104
+ key,
2105
+ value: newNode[key]
2106
+ });
2107
+ }
2108
+ }
2109
+ // Check for removed attributes
2110
+ for (const key of oldKeys) {
2111
+ if (!(key in newNode)) {
2112
+ patches.push({
2113
+ type: RemoveAttribute,
2114
+ key
2115
+ });
2116
+ }
2117
+ }
2118
+ return patches;
2119
+ };
2120
+
2121
+ const treeToArray = node => {
2122
+ const result = [node.node];
2123
+ for (const child of node.children) {
2124
+ result.push(...treeToArray(child));
2125
+ }
2126
+ return result;
2127
+ };
2128
+
2129
+ const diffChildren = (oldChildren, newChildren, patches) => {
2130
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
2131
+ // Track where we are: -1 means at parent, >= 0 means at child index
2132
+ let currentChildIndex = -1;
2133
+ // Collect indices of children to remove (we'll add these patches at the end in reverse order)
2134
+ const indicesToRemove = [];
2135
+ for (let i = 0; i < maxLength; i++) {
2136
+ const oldNode = oldChildren[i];
2137
+ const newNode = newChildren[i];
2138
+ if (!oldNode && !newNode) {
2139
+ continue;
2140
+ }
2141
+ if (!oldNode) {
2142
+ // Add new node - we should be at the parent
2143
+ if (currentChildIndex >= 0) {
2144
+ // Navigate back to parent
2145
+ patches.push({
2146
+ type: NavigateParent
2147
+ });
2148
+ currentChildIndex = -1;
2149
+ }
2150
+ // Flatten the entire subtree so renderInternal can handle it
2151
+ const flatNodes = treeToArray(newNode);
2152
+ patches.push({
2153
+ type: Add,
2154
+ nodes: flatNodes
2155
+ });
2156
+ } else if (newNode) {
2157
+ // Compare nodes to see if we need any patches
2158
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2159
+ // If nodePatches is null, the node types are incompatible - need to replace
2160
+ if (nodePatches === null) {
2161
+ // Navigate to this child
2162
+ if (currentChildIndex === -1) {
2163
+ patches.push({
2164
+ type: NavigateChild,
2165
+ index: i
2166
+ });
2167
+ currentChildIndex = i;
2168
+ } else if (currentChildIndex !== i) {
2169
+ patches.push({
2170
+ type: NavigateSibling,
2171
+ index: i
2172
+ });
2173
+ currentChildIndex = i;
2174
+ }
2175
+ // Replace the entire subtree
2176
+ const flatNodes = treeToArray(newNode);
2177
+ patches.push({
2178
+ type: Replace,
2179
+ nodes: flatNodes
2180
+ });
2181
+ // After replace, we're at the new element (same position)
2182
+ continue;
2183
+ }
2184
+ // Check if we need to recurse into children
2185
+ const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
2186
+ // Only navigate to this element if we need to do something
2187
+ if (nodePatches.length > 0 || hasChildrenToCompare) {
2188
+ // Navigate to this child if not already there
2189
+ if (currentChildIndex === -1) {
2190
+ patches.push({
2191
+ type: NavigateChild,
2192
+ index: i
2193
+ });
2194
+ currentChildIndex = i;
2195
+ } else if (currentChildIndex !== i) {
2196
+ patches.push({
2197
+ type: NavigateSibling,
2198
+ index: i
2199
+ });
2200
+ currentChildIndex = i;
2201
+ }
2202
+ // Apply node patches (these apply to the current element, not children)
2203
+ if (nodePatches.length > 0) {
2204
+ patches.push(...nodePatches);
2205
+ }
2206
+ // Compare children recursively
2207
+ if (hasChildrenToCompare) {
2208
+ diffChildren(oldNode.children, newNode.children, patches);
2209
+ }
2210
+ }
2211
+ } else {
2212
+ // Remove old node - collect the index for later removal
2213
+ indicesToRemove.push(i);
2214
+ }
2215
+ }
2216
+ // Navigate back to parent if we ended at a child
2217
+ if (currentChildIndex >= 0) {
2218
+ patches.push({
2219
+ type: NavigateParent
2220
+ });
2221
+ currentChildIndex = -1;
2222
+ }
2223
+ // Add remove patches in reverse order (highest index first)
2224
+ // This ensures indices remain valid as we remove
2225
+ for (let j = indicesToRemove.length - 1; j >= 0; j--) {
2226
+ patches.push({
2227
+ type: RemoveChild,
2228
+ index: indicesToRemove[j]
2229
+ });
2230
+ }
2231
+ };
2232
+ const diffTrees = (oldTree, newTree, patches, path) => {
2233
+ // At the root level (path.length === 0), we're already AT the element
2234
+ // So we compare the root node directly, then compare its children
2235
+ if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
2236
+ const oldNode = oldTree[0];
2237
+ const newNode = newTree[0];
2238
+ // Compare root nodes
2239
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2240
+ // If nodePatches is null, the root node types are incompatible - need to replace
2241
+ if (nodePatches === null) {
2242
+ const flatNodes = treeToArray(newNode);
2243
+ patches.push({
2244
+ type: Replace,
2245
+ nodes: flatNodes
2246
+ });
2247
+ return;
2248
+ }
2249
+ if (nodePatches.length > 0) {
2250
+ patches.push(...nodePatches);
2251
+ }
2252
+ // Compare children
2253
+ if (oldNode.children.length > 0 || newNode.children.length > 0) {
2254
+ diffChildren(oldNode.children, newNode.children, patches);
2255
+ }
2256
+ } else {
2257
+ // Non-root level or multiple root elements - use the regular comparison
2258
+ diffChildren(oldTree, newTree, patches);
2259
+ }
2260
+ };
2261
+
2262
+ const removeTrailingNavigationPatches = patches => {
2263
+ // Find the last non-navigation patch
2264
+ let lastNonNavigationIndex = -1;
2265
+ for (let i = patches.length - 1; i >= 0; i--) {
2266
+ const patch = patches[i];
2267
+ if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
2268
+ lastNonNavigationIndex = i;
2269
+ break;
2270
+ }
2271
+ }
2272
+ // Return patches up to and including the last non-navigation patch
2273
+ return lastNonNavigationIndex === -1 ? [] : patches.slice(0, lastNonNavigationIndex + 1);
2274
+ };
2275
+
2276
+ const diffTree = (oldNodes, newNodes) => {
2277
+ // Step 1: Convert flat arrays to tree structures
2278
+ const oldTree = arrayToTree(oldNodes);
2279
+ const newTree = arrayToTree(newNodes);
2280
+ // Step 3: Compare the trees
2281
+ const patches = [];
2282
+ diffTrees(oldTree, newTree, patches, []);
2283
+ // Remove trailing navigation patches since they serve no purpose
2284
+ return removeTrailingNavigationPatches(patches);
2285
+ };
2286
+
1962
2287
  const getKeyBindings = () => {
1963
2288
  return [{
1964
2289
  command: 'Source Control.acceptInput',
@@ -1970,42 +2295,42 @@ const getKeyBindings = () => {
1970
2295
  const getMenuEntries = () => {
1971
2296
  return [{
1972
2297
  command: /* TODO */'-1',
1973
- flags: None$1,
2298
+ flags: None,
1974
2299
  id: '',
1975
2300
  label: openChanges()
1976
2301
  }, {
1977
2302
  command: /* TODO */'-1',
1978
- flags: None$1,
2303
+ flags: None,
1979
2304
  id: '',
1980
2305
  label: openFile()
1981
2306
  }, {
1982
2307
  command: /* TODO */'-1',
1983
- flags: None$1,
2308
+ flags: None,
1984
2309
  id: '',
1985
2310
  label: openFileHead()
1986
2311
  }, {
1987
2312
  command: /* TODO */'-1',
1988
- flags: None$1,
2313
+ flags: None,
1989
2314
  id: '',
1990
2315
  label: discardChanges()
1991
2316
  }, {
1992
2317
  command: /* TODO */'-1',
1993
- flags: None$1,
2318
+ flags: None,
1994
2319
  id: '',
1995
2320
  label: stageChanges()
1996
2321
  }, {
1997
2322
  command: /* TODO */'-1',
1998
- flags: None$1,
2323
+ flags: None,
1999
2324
  id: '',
2000
2325
  label: addToGitignore()
2001
2326
  }, {
2002
2327
  command: /* TODO */'-1',
2003
- flags: None$1,
2328
+ flags: None,
2004
2329
  id: '',
2005
2330
  label: revealInExplorerView()
2006
2331
  }, {
2007
2332
  command: /* TODO */'-1',
2008
- flags: None$1,
2333
+ flags: None,
2009
2334
  id: '',
2010
2335
  label: openContainingFolder()
2011
2336
  }];
@@ -2075,7 +2400,7 @@ const refresh = async state => {
2075
2400
  const viewAsTree = state => {
2076
2401
  return {
2077
2402
  ...state,
2078
- viewMode: Tree$1
2403
+ viewMode: Tree
2079
2404
  };
2080
2405
  };
2081
2406
 
@@ -2419,9 +2744,30 @@ const createTextMeasurementWorkerRpc = async () => {
2419
2744
  }
2420
2745
  };
2421
2746
 
2747
+ const createExtensionManagementWorkerRpc = async () => {
2748
+ try {
2749
+ const rpc = await TransferMessagePortRpcParent.create({
2750
+ commandMap: {},
2751
+ send: port => sendMessagePortToExtensionManagementWorker(port, 0)
2752
+ });
2753
+ return rpc;
2754
+ } catch (error) {
2755
+ throw new VError(error, `Failed to create extension management rpc`);
2756
+ }
2757
+ };
2758
+
2759
+ const initializeExtensionManagementWorker = async () => {
2760
+ try {
2761
+ const rpc = await createExtensionManagementWorkerRpc();
2762
+ set$3(rpc);
2763
+ } catch {
2764
+ // ignore
2765
+ }
2766
+ };
2767
+
2422
2768
  const initialize = async () => {
2423
- const [extensionHostRpc, textRpc] = await Promise.all([createExtensionHostRpc(), createTextMeasurementWorkerRpc()]);
2424
- set$3(extensionHostRpc);
2769
+ const [extensionHostRpc, textRpc] = await Promise.all([createExtensionHostRpc(), createTextMeasurementWorkerRpc(), initializeExtensionManagementWorker()]);
2770
+ set$4(extensionHostRpc);
2425
2771
  set$1(textRpc);
2426
2772
  };
2427
2773
 
@@ -2544,7 +2890,7 @@ const getIconVirtualDom = (icon, type = Div) => {
2544
2890
  return {
2545
2891
  childCount: 0,
2546
2892
  className: `MaskIcon MaskIcon${icon}`,
2547
- role: None,
2893
+ role: None$1,
2548
2894
  type
2549
2895
  };
2550
2896
  };
@@ -2560,7 +2906,7 @@ const getButtonVirtualDom = button => {
2560
2906
  className: SourceControlButton,
2561
2907
  name: label,
2562
2908
  title: label,
2563
- type: Button$1
2909
+ type: Button$2
2564
2910
  }, getIconVirtualDom(icon, Span)];
2565
2911
  };
2566
2912
 
@@ -2632,7 +2978,7 @@ const getFileIconVirtualDom = icon => {
2632
2978
  return {
2633
2979
  childCount: 0,
2634
2980
  className: FileIcon,
2635
- role: None,
2981
+ role: None$1,
2636
2982
  src: icon,
2637
2983
  type: Img
2638
2984
  };
@@ -2721,7 +3067,7 @@ const getSourceControlListVirtualDom = items => {
2721
3067
  onClick: HandleClickAt,
2722
3068
  onPointerOut: HandleMouseOutAt,
2723
3069
  onPointerOver: HandleMouseOverAt,
2724
- role: Tree,
3070
+ role: Tree$1,
2725
3071
  type: Div
2726
3072
  }, ...items.flatMap(getSourceControlItemVirtualDom)];
2727
3073
  };
@@ -2774,14 +3120,28 @@ const getSourceControlVirtualDom = (items, splitButtonEnabled, inputPlaceholder)
2774
3120
  const renderItems = (oldState, newState) => {
2775
3121
  const {
2776
3122
  id,
3123
+ initial,
2777
3124
  inputPlaceholder,
2778
3125
  splitButtonEnabled,
2779
3126
  visibleItems
2780
3127
  } = newState;
3128
+ if (initial) {
3129
+ return [SetDom2, id, []];
3130
+ }
2781
3131
  const dom = getSourceControlVirtualDom(visibleItems, splitButtonEnabled, inputPlaceholder);
2782
3132
  return [SetDom2, id, dom];
2783
3133
  };
2784
3134
 
3135
+ const renderIncremental = (oldState, newState) => {
3136
+ const oldDom = renderItems(oldState, oldState)[2];
3137
+ const newDom = renderItems(newState, newState)[2];
3138
+ const patches = diffTree(oldDom, newDom);
3139
+ const {
3140
+ id
3141
+ } = newState;
3142
+ return ['Viewlet.setPatches', id, patches];
3143
+ };
3144
+
2785
3145
  const renderValue = (oldState, newState) => {
2786
3146
  const {
2787
3147
  id,
@@ -2796,6 +3156,8 @@ const getRenderer = diffType => {
2796
3156
  return renderCss;
2797
3157
  case RenderFocusContext:
2798
3158
  return renderFocusContext;
3159
+ case RenderIncremental:
3160
+ return renderIncremental;
2799
3161
  case RenderItems:
2800
3162
  return renderItems;
2801
3163
  case RenderValue:
@@ -2866,7 +3228,7 @@ const getActionButtonVirtualDom = action => {
2866
3228
  className: IconButton,
2867
3229
  name: label,
2868
3230
  title: id,
2869
- type: Button$1
3231
+ type: Button$2
2870
3232
  }, getIconVirtualDom(icon)];
2871
3233
  };
2872
3234
 
@@ -2927,7 +3289,7 @@ const renderEventListeners = () => {
2927
3289
  params: ['handleInput', TargetValue]
2928
3290
  }, {
2929
3291
  name: HandleContextMenu,
2930
- params: ['handleContextMenu', Button$2, ClientX, ClientY],
3292
+ params: ['handleContextMenu', Button$1, ClientX, ClientY],
2931
3293
  preventDefault: true
2932
3294
  }, {
2933
3295
  name: HandleWheel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/source-control-worker",
3
- "version": "2.23.0",
3
+ "version": "3.0.0",
4
4
  "description": "Source Control Worker",
5
5
  "keywords": [
6
6
  "Lvce Editor"