@lvce-editor/explorer-view 5.20.0 → 5.22.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.
@@ -6,42 +6,68 @@ const create$6 = () => {
6
6
  const states = Object.create(null);
7
7
  const commandMapRef = {};
8
8
  return {
9
- get(uid) {
10
- return states[uid];
9
+ clear() {
10
+ for (const key of Object.keys(states)) {
11
+ delete states[key];
12
+ }
11
13
  },
12
- set(uid, oldState, newState) {
13
- states[uid] = {
14
- oldState,
15
- newState
16
- };
14
+ diff(uid, modules, numbers) {
15
+ const {
16
+ newState,
17
+ oldState
18
+ } = states[uid];
19
+ const diffResult = [];
20
+ for (let i = 0; i < modules.length; i++) {
21
+ const fn = modules[i];
22
+ if (!fn(oldState, newState)) {
23
+ diffResult.push(numbers[i]);
24
+ }
25
+ }
26
+ return diffResult;
17
27
  },
18
28
  dispose(uid) {
19
29
  delete states[uid];
20
30
  },
31
+ get(uid) {
32
+ return states[uid];
33
+ },
34
+ getCommandIds() {
35
+ const keys = Object.keys(commandMapRef);
36
+ const ids = keys.map(toCommandId);
37
+ return ids;
38
+ },
21
39
  getKeys() {
22
40
  return Object.keys(states).map(key => {
23
41
  return Number.parseInt(key);
24
42
  });
25
43
  },
26
- clear() {
27
- for (const key of Object.keys(states)) {
28
- delete states[key];
29
- }
44
+ registerCommands(commandMap) {
45
+ Object.assign(commandMapRef, commandMap);
46
+ },
47
+ set(uid, oldState, newState) {
48
+ states[uid] = {
49
+ newState,
50
+ oldState
51
+ };
30
52
  },
31
53
  wrapCommand(fn) {
32
54
  const wrapped = async (uid, ...args) => {
33
55
  const {
34
- oldState,
35
- newState
56
+ newState,
57
+ oldState
36
58
  } = states[uid];
37
59
  const newerState = await fn(newState, ...args);
38
60
  if (oldState === newerState || newState === newerState) {
39
61
  return;
40
62
  }
41
- const latest = states[uid];
63
+ const latestOld = states[uid];
64
+ const latestNew = {
65
+ ...latestOld.newState,
66
+ ...newerState
67
+ };
42
68
  states[uid] = {
43
- oldState: latest.oldState,
44
- newState: newerState
69
+ newState: latestNew,
70
+ oldState: latestOld.oldState
45
71
  };
46
72
  };
47
73
  return wrapped;
@@ -54,28 +80,6 @@ const create$6 = () => {
54
80
  return fn(newState, ...args);
55
81
  };
56
82
  return wrapped;
57
- },
58
- diff(uid, modules, numbers) {
59
- const {
60
- oldState,
61
- newState
62
- } = states[uid];
63
- const diffResult = [];
64
- for (let i = 0; i < modules.length; i++) {
65
- const fn = modules[i];
66
- if (!fn(oldState, newState)) {
67
- diffResult.push(numbers[i]);
68
- }
69
- }
70
- return diffResult;
71
- },
72
- getCommandIds() {
73
- const keys = Object.keys(commandMapRef);
74
- const ids = keys.map(toCommandId);
75
- return ids;
76
- },
77
- registerCommands(commandMap) {
78
- Object.assign(commandMapRef, commandMap);
79
83
  }
80
84
  };
81
85
  };
@@ -145,8 +149,6 @@ const Copy$1 = 3;
145
149
  const Rename$2 = 4;
146
150
  const Remove = 5;
147
151
 
148
- const Text = 12;
149
-
150
152
  const Button$3 = 'event.button';
151
153
  const ClientX = 'event.clientX';
152
154
  const ClientY = 'event.clientY';
@@ -162,27 +164,6 @@ const ShiftKey = 'event.shiftKey';
162
164
  const TargetName = 'event.target.name';
163
165
  const TargetValue = 'event.target.value';
164
166
 
165
- const Enter = 3;
166
- const Escape = 8;
167
- const Space = 9;
168
- const End = 255;
169
- const Home = 12;
170
- const LeftArrow = 13;
171
- const UpArrow = 14;
172
- const RightArrow = 15;
173
- const DownArrow = 16;
174
- const Delete$1 = 18;
175
- const KeyA = 29;
176
- const KeyC = 31;
177
- const KeyV = 50;
178
- const KeyX = 52;
179
- const F2 = 58;
180
- const Star = 131;
181
-
182
- const CtrlCmd = 1 << 11 >>> 0;
183
- const Shift = 1 << 10 >>> 0;
184
- const Alt = 1 << 9 >>> 0;
185
-
186
167
  const FileSystemWorker$1 = 209;
187
168
  const IconThemeWorker = 7009;
188
169
  const RendererWorker = 1;
@@ -193,6 +174,7 @@ const FocusSelector = 'Viewlet.focusSelector';
193
174
  const SetCss = 'Viewlet.setCss';
194
175
  const SetDom2 = 'Viewlet.setDom2';
195
176
  const SetFocusContext = 'Viewlet.setFocusContext';
177
+ const SetPatches = 'Viewlet.setPatches';
196
178
 
197
179
  const FocusExplorer = 13;
198
180
  const FocusExplorerEditBox = 14;
@@ -611,7 +593,7 @@ const getFirstEvent = (eventEmitter, eventMap) => {
611
593
  return promise;
612
594
  };
613
595
  const Message$1 = 3;
614
- const create$5 = async ({
596
+ const create$5$1 = async ({
615
597
  isMessagePortOpen,
616
598
  messagePort
617
599
  }) => {
@@ -662,7 +644,7 @@ const wrap$5 = messagePort => {
662
644
  };
663
645
  const IpcParentWithMessagePort$1 = {
664
646
  __proto__: null,
665
- create: create$5,
647
+ create: create$5$1,
666
648
  signal: signal$1,
667
649
  wrap: wrap$5
668
650
  };
@@ -868,7 +850,7 @@ const getErrorProperty = (error, prettyError) => {
868
850
  }
869
851
  };
870
852
  };
871
- const create$1$2 = (id, error) => {
853
+ const create$1$1 = (id, error) => {
872
854
  return {
873
855
  jsonrpc: Two$1,
874
856
  id,
@@ -879,9 +861,9 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
879
861
  const prettyError = preparePrettyError(error);
880
862
  logError(error, prettyError);
881
863
  const errorProperty = getErrorProperty(error, prettyError);
882
- return create$1$2(id, errorProperty);
864
+ return create$1$1(id, errorProperty);
883
865
  };
884
- const create$3 = (message, result) => {
866
+ const create$4 = (message, result) => {
885
867
  return {
886
868
  jsonrpc: Two$1,
887
869
  id: message.id,
@@ -890,7 +872,7 @@ const create$3 = (message, result) => {
890
872
  };
891
873
  const getSuccessResponse = (message, result) => {
892
874
  const resultProperty = result ?? null;
893
- return create$3(message, resultProperty);
875
+ return create$4(message, resultProperty);
894
876
  };
895
877
  const getErrorResponseSimple = (id, error) => {
896
878
  return {
@@ -1004,14 +986,14 @@ const execute = (command, ...args) => {
1004
986
  };
1005
987
 
1006
988
  const Two = '2.0';
1007
- const create$s = (method, params) => {
989
+ const create$t = (method, params) => {
1008
990
  return {
1009
991
  jsonrpc: Two,
1010
992
  method,
1011
993
  params
1012
994
  };
1013
995
  };
1014
- const create$r = (id, method, params) => {
996
+ const create$s = (id, method, params) => {
1015
997
  const message = {
1016
998
  id,
1017
999
  jsonrpc: Two,
@@ -1021,14 +1003,14 @@ const create$r = (id, method, params) => {
1021
1003
  return message;
1022
1004
  };
1023
1005
  let id = 0;
1024
- const create$q = () => {
1006
+ const create$r = () => {
1025
1007
  return ++id;
1026
1008
  };
1027
1009
 
1028
1010
  /* eslint-disable n/no-unsupported-features/es-syntax */
1029
1011
 
1030
1012
  const registerPromise = map => {
1031
- const id = create$q();
1013
+ const id = create$r();
1032
1014
  const {
1033
1015
  promise,
1034
1016
  resolve
@@ -1046,7 +1028,7 @@ const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer)
1046
1028
  id,
1047
1029
  promise
1048
1030
  } = registerPromise(callbacks);
1049
- const message = create$r(id, method, params);
1031
+ const message = create$s(id, method, params);
1050
1032
  if (useSendAndTransfer && ipc.sendAndTransfer) {
1051
1033
  ipc.sendAndTransfer(message);
1052
1034
  } else {
@@ -1082,7 +1064,7 @@ const createRpc = ipc => {
1082
1064
  * @deprecated
1083
1065
  */
1084
1066
  send(method, ...params) {
1085
- const message = create$s(method, params);
1067
+ const message = create$t(method, params);
1086
1068
  ipc.send(message);
1087
1069
  }
1088
1070
  };
@@ -1148,13 +1130,13 @@ const createSharedLazyRpc = factory => {
1148
1130
  }
1149
1131
  };
1150
1132
  };
1151
- const create$i = async ({
1133
+ const create$j = async ({
1152
1134
  commandMap,
1153
1135
  isMessagePortOpen,
1154
1136
  send
1155
1137
  }) => {
1156
1138
  return createSharedLazyRpc(() => {
1157
- return create$2({
1139
+ return create$3({
1158
1140
  commandMap,
1159
1141
  isMessagePortOpen,
1160
1142
  send
@@ -1163,9 +1145,9 @@ const create$i = async ({
1163
1145
  };
1164
1146
  const LazyTransferMessagePortRpcParent = {
1165
1147
  __proto__: null,
1166
- create: create$i
1148
+ create: create$j
1167
1149
  };
1168
- const create$4 = async ({
1150
+ const create$5 = async ({
1169
1151
  commandMap,
1170
1152
  isMessagePortOpen = true,
1171
1153
  messagePort
@@ -1182,7 +1164,7 @@ const create$4 = async ({
1182
1164
  messagePort.start();
1183
1165
  return rpc;
1184
1166
  };
1185
- const create$2 = async ({
1167
+ const create$3 = async ({
1186
1168
  commandMap,
1187
1169
  isMessagePortOpen,
1188
1170
  send
@@ -1192,13 +1174,13 @@ const create$2 = async ({
1192
1174
  port2
1193
1175
  } = new MessageChannel();
1194
1176
  await send(port1);
1195
- return create$4({
1177
+ return create$5({
1196
1178
  commandMap,
1197
1179
  isMessagePortOpen,
1198
1180
  messagePort: port2
1199
1181
  });
1200
1182
  };
1201
- const create$1$1 = async ({
1183
+ const create$2 = async ({
1202
1184
  commandMap
1203
1185
  }) => {
1204
1186
  // TODO create a commandMap per rpc instance
@@ -1210,7 +1192,7 @@ const create$1$1 = async ({
1210
1192
  };
1211
1193
  const WebWorkerRpcClient = {
1212
1194
  __proto__: null,
1213
- create: create$1$1
1195
+ create: create$2
1214
1196
  };
1215
1197
  const createMockRpc = ({
1216
1198
  commandMap
@@ -1871,7 +1853,7 @@ const treeToArrayInternal = (map, root, items, path, depth) => {
1871
1853
  }
1872
1854
  };
1873
1855
 
1874
- const treeToArray = (map, root) => {
1856
+ const treeToArray$1 = (map, root) => {
1875
1857
  const items = [];
1876
1858
  treeToArrayInternal(map, root, items, '', 1);
1877
1859
  return items;
@@ -1898,7 +1880,7 @@ const Copy = 'Copy';
1898
1880
  const CopyPath = 'Copy Path';
1899
1881
  const CopyRelativePath = 'Copy Relative Path';
1900
1882
  const Cut = 'Cut';
1901
- const Delete = 'Delete';
1883
+ const Delete$1 = 'Delete';
1902
1884
  const FileNameCannotStartWithSlash = 'A file or folder name cannot start with a slash.';
1903
1885
  const FileOrFolderAlreadyExists = 'A file or folder **{PH1}** already exists at this location. Please choose a different name.';
1904
1886
  const FileOrFolderNameMustBeProvider = 'A file or folder name must be provided.';
@@ -1914,7 +1896,7 @@ const RefreshExplorer = 'Refresh Explorer';
1914
1896
  const Rename = 'Rename';
1915
1897
  const TheNameIsNotValid = 'The name **{0}** is not valid as a file or folder name. Please choose a different name.';
1916
1898
  const TypeAFileName = 'Type file name. Press Enter to confirm or Escape to cancel.'; // TODO use keybinding
1917
- const YouHaveNotYetOpenedAFolder = 'You have not yet opened a folder';
1899
+ const YouHaveNotYetOpenedAFolder = 'You have not yet opened a folder.';
1918
1900
 
1919
1901
  const newFile$1 = () => {
1920
1902
  return i18nString(NewFile$2);
@@ -1947,7 +1929,7 @@ const rename = () => {
1947
1929
  return i18nString(Rename);
1948
1930
  };
1949
1931
  const deleteItem = () => {
1950
- return i18nString(Delete);
1932
+ return i18nString(Delete$1);
1951
1933
  };
1952
1934
  const refresh$1 = () => {
1953
1935
  return i18nString(RefreshExplorer);
@@ -2046,7 +2028,7 @@ const acceptCreate = async (state, newDirentType) => {
2046
2028
  const tree = createTree(items, root);
2047
2029
  const childTree = createTree(children, root);
2048
2030
  const merged = mergeTrees(tree, childTree);
2049
- const newItems = treeToArray(merged, root);
2031
+ const newItems = treeToArray$1(merged, root);
2050
2032
  const dirents = newItems;
2051
2033
  const newFocusedIndex = getIndex(newItems, absolutePath);
2052
2034
  await refreshWorkspace();
@@ -2136,7 +2118,7 @@ const acceptRename = async state => {
2136
2118
  const tree = createTree(items, root);
2137
2119
  const update = computeExplorerRenamedDirentUpdate(root, dirname, oldUri, children, tree, newUri);
2138
2120
  const newTree = updateTree2(tree, update);
2139
- const newDirents = treeToArray(newTree, root);
2121
+ const newDirents = treeToArray$1(newTree, root);
2140
2122
  const newFocusedIndex = getIndex(newDirents, newUri);
2141
2123
  return {
2142
2124
  ...state,
@@ -2308,7 +2290,6 @@ const writeText = async text => {
2308
2290
  await writeClipBoardText(text);
2309
2291
  };
2310
2292
  const readNativeFiles = async () => {
2311
- // @ts-ignore
2312
2293
  return invoke$2('ClipBoard.readNativeFiles');
2313
2294
  };
2314
2295
  const writeNativeFiles = async (type, files) => {
@@ -2519,6 +2500,29 @@ const Viewlet = 'Viewlet';
2519
2500
  const Welcome = 'Welcome';
2520
2501
  const WelcomeMessage = 'WelcomeMessage';
2521
2502
 
2503
+ const Text = 12;
2504
+
2505
+ const Enter = 3;
2506
+ const Escape = 8;
2507
+ const Space = 9;
2508
+ const End = 255;
2509
+ const Home = 12;
2510
+ const LeftArrow = 13;
2511
+ const UpArrow = 14;
2512
+ const RightArrow = 15;
2513
+ const DownArrow = 16;
2514
+ const Delete = 18;
2515
+ const KeyA = 29;
2516
+ const KeyC = 31;
2517
+ const KeyV = 50;
2518
+ const KeyX = 52;
2519
+ const F2 = 58;
2520
+ const Star = 131;
2521
+
2522
+ const CtrlCmd = 1 << 11 >>> 0;
2523
+ const Shift = 1 << 10 >>> 0;
2524
+ const Alt = 1 << 9 >>> 0;
2525
+
2522
2526
  const mergeClassNames = (...classNames) => {
2523
2527
  return classNames.filter(Boolean).join(' ');
2524
2528
  };
@@ -2538,6 +2542,283 @@ const text = data => {
2538
2542
  };
2539
2543
  };
2540
2544
 
2545
+ const SetText = 1;
2546
+ const Replace = 2;
2547
+ const SetAttribute = 3;
2548
+ const RemoveAttribute = 4;
2549
+ const Add = 6;
2550
+ const NavigateChild = 7;
2551
+ const NavigateParent = 8;
2552
+ const RemoveChild = 9;
2553
+ const NavigateSibling = 10;
2554
+
2555
+ const isKey = key => {
2556
+ return key !== 'type' && key !== 'childCount';
2557
+ };
2558
+
2559
+ const getKeys = node => {
2560
+ const keys = Object.keys(node).filter(isKey);
2561
+ return keys;
2562
+ };
2563
+
2564
+ const arrayToTree = nodes => {
2565
+ const result = [];
2566
+ let i = 0;
2567
+ while (i < nodes.length) {
2568
+ const node = nodes[i];
2569
+ const {
2570
+ children,
2571
+ nodesConsumed
2572
+ } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
2573
+ result.push({
2574
+ node,
2575
+ children
2576
+ });
2577
+ i += 1 + nodesConsumed;
2578
+ }
2579
+ return result;
2580
+ };
2581
+ const getChildrenWithCount = (nodes, startIndex, childCount) => {
2582
+ if (childCount === 0) {
2583
+ return {
2584
+ children: [],
2585
+ nodesConsumed: 0
2586
+ };
2587
+ }
2588
+ const children = [];
2589
+ let i = startIndex;
2590
+ let remaining = childCount;
2591
+ let totalConsumed = 0;
2592
+ while (remaining > 0 && i < nodes.length) {
2593
+ const node = nodes[i];
2594
+ const nodeChildCount = node.childCount || 0;
2595
+ const {
2596
+ children: nodeChildren,
2597
+ nodesConsumed
2598
+ } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
2599
+ children.push({
2600
+ node,
2601
+ children: nodeChildren
2602
+ });
2603
+ const nodeSize = 1 + nodesConsumed;
2604
+ i += nodeSize;
2605
+ totalConsumed += nodeSize;
2606
+ remaining--;
2607
+ }
2608
+ return {
2609
+ children,
2610
+ nodesConsumed: totalConsumed
2611
+ };
2612
+ };
2613
+
2614
+ const compareNodes = (oldNode, newNode) => {
2615
+ const patches = [];
2616
+ // Check if node type changed - return null to signal incompatible nodes
2617
+ // (caller should handle this with a Replace operation)
2618
+ if (oldNode.type !== newNode.type) {
2619
+ return null;
2620
+ }
2621
+ // Handle text nodes
2622
+ if (oldNode.type === Text && newNode.type === Text) {
2623
+ if (oldNode.text !== newNode.text) {
2624
+ patches.push({
2625
+ type: SetText,
2626
+ value: newNode.text
2627
+ });
2628
+ }
2629
+ return patches;
2630
+ }
2631
+ // Compare attributes
2632
+ const oldKeys = getKeys(oldNode);
2633
+ const newKeys = getKeys(newNode);
2634
+ // Check for attribute changes
2635
+ for (const key of newKeys) {
2636
+ if (oldNode[key] !== newNode[key]) {
2637
+ patches.push({
2638
+ type: SetAttribute,
2639
+ key,
2640
+ value: newNode[key]
2641
+ });
2642
+ }
2643
+ }
2644
+ // Check for removed attributes
2645
+ for (const key of oldKeys) {
2646
+ if (!(key in newNode)) {
2647
+ patches.push({
2648
+ type: RemoveAttribute,
2649
+ key
2650
+ });
2651
+ }
2652
+ }
2653
+ return patches;
2654
+ };
2655
+
2656
+ const treeToArray = node => {
2657
+ const result = [node.node];
2658
+ for (const child of node.children) {
2659
+ result.push(...treeToArray(child));
2660
+ }
2661
+ return result;
2662
+ };
2663
+
2664
+ const diffChildren = (oldChildren, newChildren, patches) => {
2665
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
2666
+ // Track where we are: -1 means at parent, >= 0 means at child index
2667
+ let currentChildIndex = -1;
2668
+ // Collect indices of children to remove (we'll add these patches at the end in reverse order)
2669
+ const indicesToRemove = [];
2670
+ for (let i = 0; i < maxLength; i++) {
2671
+ const oldNode = oldChildren[i];
2672
+ const newNode = newChildren[i];
2673
+ if (!oldNode && !newNode) {
2674
+ continue;
2675
+ }
2676
+ if (!oldNode) {
2677
+ // Add new node - we should be at the parent
2678
+ if (currentChildIndex >= 0) {
2679
+ // Navigate back to parent
2680
+ patches.push({
2681
+ type: NavigateParent
2682
+ });
2683
+ currentChildIndex = -1;
2684
+ }
2685
+ // Flatten the entire subtree so renderInternal can handle it
2686
+ const flatNodes = treeToArray(newNode);
2687
+ patches.push({
2688
+ type: Add,
2689
+ nodes: flatNodes
2690
+ });
2691
+ } else if (newNode) {
2692
+ // Compare nodes to see if we need any patches
2693
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2694
+ // If nodePatches is null, the node types are incompatible - need to replace
2695
+ if (nodePatches === null) {
2696
+ // Navigate to this child
2697
+ if (currentChildIndex === -1) {
2698
+ patches.push({
2699
+ type: NavigateChild,
2700
+ index: i
2701
+ });
2702
+ currentChildIndex = i;
2703
+ } else if (currentChildIndex !== i) {
2704
+ patches.push({
2705
+ type: NavigateSibling,
2706
+ index: i
2707
+ });
2708
+ currentChildIndex = i;
2709
+ }
2710
+ // Replace the entire subtree
2711
+ const flatNodes = treeToArray(newNode);
2712
+ patches.push({
2713
+ type: Replace,
2714
+ nodes: flatNodes
2715
+ });
2716
+ // After replace, we're at the new element (same position)
2717
+ continue;
2718
+ }
2719
+ // Check if we need to recurse into children
2720
+ const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
2721
+ // Only navigate to this element if we need to do something
2722
+ if (nodePatches.length > 0 || hasChildrenToCompare) {
2723
+ // Navigate to this child if not already there
2724
+ if (currentChildIndex === -1) {
2725
+ patches.push({
2726
+ type: NavigateChild,
2727
+ index: i
2728
+ });
2729
+ currentChildIndex = i;
2730
+ } else if (currentChildIndex !== i) {
2731
+ patches.push({
2732
+ type: NavigateSibling,
2733
+ index: i
2734
+ });
2735
+ currentChildIndex = i;
2736
+ }
2737
+ // Apply node patches (these apply to the current element, not children)
2738
+ if (nodePatches.length > 0) {
2739
+ patches.push(...nodePatches);
2740
+ }
2741
+ // Compare children recursively
2742
+ if (hasChildrenToCompare) {
2743
+ diffChildren(oldNode.children, newNode.children, patches);
2744
+ }
2745
+ }
2746
+ } else {
2747
+ // Remove old node - collect the index for later removal
2748
+ indicesToRemove.push(i);
2749
+ }
2750
+ }
2751
+ // Navigate back to parent if we ended at a child
2752
+ if (currentChildIndex >= 0) {
2753
+ patches.push({
2754
+ type: NavigateParent
2755
+ });
2756
+ currentChildIndex = -1;
2757
+ }
2758
+ // Add remove patches in reverse order (highest index first)
2759
+ // This ensures indices remain valid as we remove
2760
+ for (let j = indicesToRemove.length - 1; j >= 0; j--) {
2761
+ patches.push({
2762
+ type: RemoveChild,
2763
+ index: indicesToRemove[j]
2764
+ });
2765
+ }
2766
+ };
2767
+ const diffTrees = (oldTree, newTree, patches, path) => {
2768
+ // At the root level (path.length === 0), we're already AT the element
2769
+ // So we compare the root node directly, then compare its children
2770
+ if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
2771
+ const oldNode = oldTree[0];
2772
+ const newNode = newTree[0];
2773
+ // Compare root nodes
2774
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2775
+ // If nodePatches is null, the root node types are incompatible - need to replace
2776
+ if (nodePatches === null) {
2777
+ const flatNodes = treeToArray(newNode);
2778
+ patches.push({
2779
+ type: Replace,
2780
+ nodes: flatNodes
2781
+ });
2782
+ return;
2783
+ }
2784
+ if (nodePatches.length > 0) {
2785
+ patches.push(...nodePatches);
2786
+ }
2787
+ // Compare children
2788
+ if (oldNode.children.length > 0 || newNode.children.length > 0) {
2789
+ diffChildren(oldNode.children, newNode.children, patches);
2790
+ }
2791
+ } else {
2792
+ // Non-root level or multiple root elements - use the regular comparison
2793
+ diffChildren(oldTree, newTree, patches);
2794
+ }
2795
+ };
2796
+
2797
+ const removeTrailingNavigationPatches = patches => {
2798
+ // Find the last non-navigation patch
2799
+ let lastNonNavigationIndex = -1;
2800
+ for (let i = patches.length - 1; i >= 0; i--) {
2801
+ const patch = patches[i];
2802
+ if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
2803
+ lastNonNavigationIndex = i;
2804
+ break;
2805
+ }
2806
+ }
2807
+ // Return patches up to and including the last non-navigation patch
2808
+ return lastNonNavigationIndex === -1 ? [] : patches.slice(0, lastNonNavigationIndex + 1);
2809
+ };
2810
+
2811
+ const diffTree = (oldNodes, newNodes) => {
2812
+ // Step 1: Convert flat arrays to tree structures
2813
+ const oldTree = arrayToTree(oldNodes);
2814
+ const newTree = arrayToTree(newNodes);
2815
+ // Step 3: Compare the trees
2816
+ const patches = [];
2817
+ diffTrees(oldTree, newTree, patches, []);
2818
+ // Remove trailing navigation patches since they serve no purpose
2819
+ return removeTrailingNavigationPatches(patches);
2820
+ };
2821
+
2541
2822
  const getTreeItemClassName = (isSelected, isFocused, isDropping, useChevrons, indent, decoration) => {
2542
2823
  let className = TreeItem$1;
2543
2824
  className = mergeClassNames(className, `Indent-${indent}`);
@@ -2611,7 +2892,6 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
2611
2892
  ariaExpanded,
2612
2893
  chevron,
2613
2894
  className,
2614
- // @ts-ignore
2615
2895
  decoration,
2616
2896
  hasEditingError: isEditing && Boolean(editingErrorMessage),
2617
2897
  icon,
@@ -2718,6 +2998,7 @@ const create = (id, uri, x, y, width, height, args, parentUid, platform = 0, ass
2718
2998
  height,
2719
2999
  hoverIndex: -1,
2720
3000
  icons: [],
3001
+ initial: false,
2721
3002
  inputSource: 0,
2722
3003
  isPointerDown: false,
2723
3004
  itemHeight: ListItem,
@@ -2782,6 +3063,7 @@ const RenderValue = 8;
2782
3063
  const RenderSelection = 9;
2783
3064
  const RenderDragData = 10;
2784
3065
  const RenderCss = 11;
3066
+ const RenderIncremental = 12;
2785
3067
 
2786
3068
  const isEqual$1 = (oldState, newState) => {
2787
3069
  if (newState.focus !== Input$1) {
@@ -3134,7 +3416,7 @@ const getKeyBindings = () => {
3134
3416
  when: FocusExplorerEditBox
3135
3417
  }, {
3136
3418
  command: 'Explorer.removeDirent',
3137
- key: Delete$1,
3419
+ key: Delete,
3138
3420
  when: FocusExplorer
3139
3421
  }, {
3140
3422
  command: 'Explorer.focusNone',
@@ -3570,10 +3852,18 @@ const getNewDirentsForNewDirent = async (items, focusedIndex, type, root) => {
3570
3852
  const parentIndex = focusedIndex;
3571
3853
  const itemsBeforeParent = items.slice(0, parentIndex);
3572
3854
  const itemsAfterChildren = items.slice(parentIndex + updatedChildren.length);
3573
- const updatedParent = {
3855
+ let updatedParent = {
3574
3856
  ...items[parentIndex],
3575
3857
  setSize: (items[parentIndex]?.setSize || 0) + 1
3576
3858
  };
3859
+
3860
+ // If the parent is a closed Directory, expand it
3861
+ if (updatedParent.type === Directory) {
3862
+ updatedParent = {
3863
+ ...updatedParent,
3864
+ type: DirectoryExpanded
3865
+ };
3866
+ }
3577
3867
  return [...itemsBeforeParent, updatedParent, ...updatedChildren, ...itemsAfterChildren];
3578
3868
  };
3579
3869
 
@@ -3963,7 +4253,6 @@ const handleClickCurrentButKeepFocus = state => {
3963
4253
  };
3964
4254
 
3965
4255
  const openFolder = async () => {
3966
- // @ts-ignore
3967
4256
  await invoke$2(`Dialog.openFolder`);
3968
4257
  };
3969
4258
 
@@ -4566,8 +4855,6 @@ const handleKeyDown = (state, key) => {
4566
4855
  if (timeout) {
4567
4856
  clearTimeout(timeout);
4568
4857
  }
4569
-
4570
- // @ts-ignore
4571
4858
  timeout = setTimeout(async () => {
4572
4859
  await invoke$2('Explorer.cancelTypeAhead');
4573
4860
  }, focusWordTimeout);
@@ -5060,7 +5347,6 @@ const getSavedRoot = (savedState, workspacePath) => {
5060
5347
  return workspacePath;
5061
5348
  };
5062
5349
  const loadContent = async (state, savedState) => {
5063
- // @ts-ignore
5064
5350
  const {
5065
5351
  assetDir,
5066
5352
  platform
@@ -5092,6 +5378,7 @@ const loadContent = async (state, savedState) => {
5092
5378
  decorations,
5093
5379
  deltaY,
5094
5380
  excluded,
5381
+ initial: true,
5095
5382
  items: restoredDirents,
5096
5383
  maxIndent: 10,
5097
5384
  minLineY,
@@ -5148,7 +5435,6 @@ const openContainingFolder = async state => {
5148
5435
  const confirmDelete = async paths => {
5149
5436
  // TODO use i18n string
5150
5437
  const message = paths.length === 1 ? `Are you sure you want to delete "${paths[0]}"?` : `Are you sure you want to delete ${paths.length} items?`;
5151
- // @ts-ignore
5152
5438
  const result = await confirm(message);
5153
5439
  return result === true;
5154
5440
  };
@@ -5694,6 +5980,13 @@ const renderItems = (oldState, newState) => {
5694
5980
  return [SetDom2, dom];
5695
5981
  };
5696
5982
 
5983
+ const renderIncremental = (oldState, newState) => {
5984
+ const oldDom = renderItems(oldState, oldState)[1];
5985
+ const newDom = renderItems(newState, newState)[1];
5986
+ const patches = diffTree(oldDom, newDom);
5987
+ return [SetPatches, newState.uid, patches];
5988
+ };
5989
+
5697
5990
  const renderValue = (oldState, newState) => {
5698
5991
  if (newState.inputSource === User) {
5699
5992
  return [];
@@ -5714,6 +6007,8 @@ const getRenderer = diffType => {
5714
6007
  return renderFocus;
5715
6008
  case RenderFocusContext:
5716
6009
  return renderFocusContext;
6010
+ case RenderIncremental:
6011
+ return renderIncremental;
5717
6012
  case RenderItems:
5718
6013
  return renderItems;
5719
6014
  case RenderSelection:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "5.20.0",
3
+ "version": "5.22.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",