@lvce-editor/explorer-view 1.11.0 → 1.13.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.
@@ -107,27 +107,6 @@ const string = value => {
107
107
  }
108
108
  };
109
109
 
110
- const walkValue = (value, transferrables, isTransferrable) => {
111
- if (!value) {
112
- return;
113
- }
114
- if (isTransferrable(value)) {
115
- transferrables.push(value);
116
- return;
117
- }
118
- if (Array.isArray(value)) {
119
- for (const item of value) {
120
- walkValue(item, transferrables, isTransferrable);
121
- }
122
- return;
123
- }
124
- if (typeof value === 'object') {
125
- for (const property of Object.values(value)) {
126
- walkValue(property, transferrables, isTransferrable);
127
- }
128
- return;
129
- }
130
- };
131
110
  const isMessagePort = value => {
132
111
  return value && value instanceof MessagePort;
133
112
  };
@@ -152,6 +131,27 @@ const isTransferrable = value => {
152
131
  }
153
132
  return false;
154
133
  };
134
+ const walkValue = (value, transferrables, isTransferrable) => {
135
+ if (!value) {
136
+ return;
137
+ }
138
+ if (isTransferrable(value)) {
139
+ transferrables.push(value);
140
+ return;
141
+ }
142
+ if (Array.isArray(value)) {
143
+ for (const item of value) {
144
+ walkValue(item, transferrables, isTransferrable);
145
+ }
146
+ return;
147
+ }
148
+ if (typeof value === 'object') {
149
+ for (const property of Object.values(value)) {
150
+ walkValue(property, transferrables, isTransferrable);
151
+ }
152
+ return;
153
+ }
154
+ };
155
155
  const getTransferrables = value => {
156
156
  const transferrables = [];
157
157
  walkValue(value, transferrables, isTransferrable);
@@ -184,30 +184,35 @@ const NewLine$1 = '\n';
184
184
  const joinLines$1 = lines => {
185
185
  return lines.join(NewLine$1);
186
186
  };
187
- const splitLines$1 = lines => {
188
- return lines.split(NewLine$1);
189
- };
190
- const isModuleNotFoundMessage = line => {
191
- return line.includes('[ERR_MODULE_NOT_FOUND]');
187
+ const RE_AT = /^\s+at/;
188
+ const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
189
+ const isNormalStackLine = line => {
190
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
192
191
  };
193
- const getModuleNotFoundError = stderr => {
194
- const lines = splitLines$1(stderr);
195
- const messageIndex = lines.findIndex(isModuleNotFoundMessage);
196
- const message = lines[messageIndex];
192
+ const getDetails = lines => {
193
+ const index = lines.findIndex(isNormalStackLine);
194
+ if (index === -1) {
195
+ return {
196
+ actualMessage: joinLines$1(lines),
197
+ rest: []
198
+ };
199
+ }
200
+ let lastIndex = index - 1;
201
+ while (++lastIndex < lines.length) {
202
+ if (!isNormalStackLine(lines[lastIndex])) {
203
+ break;
204
+ }
205
+ }
197
206
  return {
198
- message,
199
- code: ERR_MODULE_NOT_FOUND
207
+ actualMessage: lines[index - 1],
208
+ rest: lines.slice(index, lastIndex)
200
209
  };
201
210
  };
202
- const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
203
- const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
211
+ const splitLines$1 = lines => {
212
+ return lines.split(NewLine$1);
213
+ };
204
214
  const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
205
215
  const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
206
- const RE_AT = /^\s+at/;
207
- const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
208
- const isUnhelpfulNativeModuleError = stderr => {
209
- return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
210
- };
211
216
  const isMessageCodeBlockStartIndex = line => {
212
217
  return RE_MESSAGE_CODE_BLOCK_START.test(line);
213
218
  };
@@ -222,51 +227,46 @@ const getMessageCodeBlock = stderr => {
222
227
  const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
223
228
  return relevantMessage;
224
229
  };
225
- const getNativeModuleErrorMessage = stderr => {
226
- const message = getMessageCodeBlock(stderr);
230
+ const isModuleNotFoundMessage = line => {
231
+ return line.includes('[ERR_MODULE_NOT_FOUND]');
232
+ };
233
+ const getModuleNotFoundError = stderr => {
234
+ const lines = splitLines$1(stderr);
235
+ const messageIndex = lines.findIndex(isModuleNotFoundMessage);
236
+ const message = lines[messageIndex];
227
237
  return {
228
- message: `Incompatible native node module: ${message}`,
229
- code: E_INCOMPATIBLE_NATIVE_MODULE
238
+ message,
239
+ code: ERR_MODULE_NOT_FOUND
230
240
  };
231
241
  };
232
- const isModulesSyntaxError = stderr => {
242
+ const isModuleNotFoundError = stderr => {
233
243
  if (!stderr) {
234
244
  return false;
235
245
  }
236
- return stderr.includes('SyntaxError: Cannot use import statement outside a module');
237
- };
238
- const getModuleSyntaxError = () => {
239
- return {
240
- message: `ES Modules are not supported in electron`,
241
- code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
242
- };
246
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
243
247
  };
244
- const isModuleNotFoundError = stderr => {
248
+ const isModulesSyntaxError = stderr => {
245
249
  if (!stderr) {
246
250
  return false;
247
251
  }
248
- return stderr.includes('ERR_MODULE_NOT_FOUND');
252
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module');
249
253
  };
250
- const isNormalStackLine = line => {
251
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
254
+ const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
255
+ const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
256
+ const isUnhelpfulNativeModuleError = stderr => {
257
+ return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
252
258
  };
253
- const getDetails = lines => {
254
- const index = lines.findIndex(isNormalStackLine);
255
- if (index === -1) {
256
- return {
257
- actualMessage: joinLines$1(lines),
258
- rest: []
259
- };
260
- }
261
- let lastIndex = index - 1;
262
- while (++lastIndex < lines.length) {
263
- if (!isNormalStackLine(lines[lastIndex])) {
264
- break;
265
- }
266
- }
259
+ const getNativeModuleErrorMessage = stderr => {
260
+ const message = getMessageCodeBlock(stderr);
267
261
  return {
268
- actualMessage: lines[index - 1],
269
- rest: lines.slice(index, lastIndex)
262
+ message: `Incompatible native node module: ${message}`,
263
+ code: E_INCOMPATIBLE_NATIVE_MODULE
264
+ };
265
+ };
266
+ const getModuleSyntaxError = () => {
267
+ return {
268
+ message: `ES Modules are not supported in electron`,
269
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
270
270
  };
271
271
  };
272
272
  const getHelpfulChildProcessError = (stdout, stderr) => {
@@ -285,7 +285,7 @@ const getHelpfulChildProcessError = (stdout, stderr) => {
285
285
  rest
286
286
  } = getDetails(lines);
287
287
  return {
288
- message: `${actualMessage}`,
288
+ message: actualMessage,
289
289
  code: '',
290
290
  stack: rest
291
291
  };
@@ -327,7 +327,7 @@ const listen$7 = () => {
327
327
  }
328
328
  return globalThis;
329
329
  };
330
- const signal$7 = global => {
330
+ const signal$8 = global => {
331
331
  global.postMessage(readyMessage);
332
332
  };
333
333
  class IpcChildWithModuleWorker extends Ipc {
@@ -353,7 +353,7 @@ class IpcChildWithModuleWorker extends Ipc {
353
353
  this._rawIpc.addEventListener('message', callback);
354
354
  }
355
355
  }
356
- const wrap$e = global => {
356
+ const wrap$f = global => {
357
357
  return new IpcChildWithModuleWorker(global);
358
358
  };
359
359
  const withResolvers = () => {
@@ -362,6 +362,7 @@ const withResolvers = () => {
362
362
  _resolve = resolve;
363
363
  });
364
364
  return {
365
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
365
366
  resolve: _resolve,
366
367
  promise
367
368
  };
@@ -380,8 +381,8 @@ const waitForFirstMessage = async port => {
380
381
  };
381
382
  const listen$6 = async () => {
382
383
  const parentIpcRaw = listen$7();
383
- signal$7(parentIpcRaw);
384
- const parentIpc = wrap$e(parentIpcRaw);
384
+ signal$8(parentIpcRaw);
385
+ const parentIpc = wrap$f(parentIpcRaw);
385
386
  const firstMessage = await waitForFirstMessage(parentIpc);
386
387
  if (firstMessage.method !== 'initialize') {
387
388
  throw new IpcError('unexpected first message');
@@ -400,9 +401,6 @@ const listen$6 = async () => {
400
401
  return globalThis;
401
402
  };
402
403
  class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
403
- constructor(port) {
404
- super(port);
405
- }
406
404
  getData(event) {
407
405
  return getData$2(event);
408
406
  }
@@ -426,13 +424,13 @@ class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
426
424
  this._rawIpc.start();
427
425
  }
428
426
  }
429
- const wrap$d = port => {
427
+ const wrap$e = port => {
430
428
  return new IpcChildWithModuleWorkerAndMessagePort(port);
431
429
  };
432
430
  const IpcChildWithModuleWorkerAndMessagePort$1 = {
433
431
  __proto__: null,
434
432
  listen: listen$6,
435
- wrap: wrap$d
433
+ wrap: wrap$e
436
434
  };
437
435
 
438
436
  const Two = '2.0';
@@ -444,10 +442,10 @@ const create$4 = (method, params) => {
444
442
  };
445
443
  };
446
444
  const callbacks = Object.create(null);
447
- const set = (id, fn) => {
445
+ const set$1 = (id, fn) => {
448
446
  callbacks[id] = fn;
449
447
  };
450
- const get = id => {
448
+ const get$1 = id => {
451
449
  return callbacks[id];
452
450
  };
453
451
  const remove$1 = id => {
@@ -457,31 +455,18 @@ let id = 0;
457
455
  const create$3 = () => {
458
456
  return ++id;
459
457
  };
460
- const warn = (...args) => {
461
- console.warn(...args);
462
- };
463
458
  const registerPromise = () => {
464
459
  const id = create$3();
465
460
  const {
466
461
  resolve,
467
462
  promise
468
463
  } = Promise.withResolvers();
469
- set(id, resolve);
464
+ set$1(id, resolve);
470
465
  return {
471
466
  id,
472
467
  promise
473
468
  };
474
469
  };
475
- const resolve = (id, response) => {
476
- const fn = get(id);
477
- if (!fn) {
478
- console.log(response);
479
- warn(`callback ${id} may already be disposed`);
480
- return;
481
- }
482
- fn(response);
483
- remove$1(id);
484
- };
485
470
  const create$2 = (method, params) => {
486
471
  const {
487
472
  id,
@@ -629,6 +614,19 @@ const unwrapJsonRpcResult = responseMessage => {
629
614
  }
630
615
  throw new JsonRpcError('unexpected response message');
631
616
  };
617
+ const warn = (...args) => {
618
+ console.warn(...args);
619
+ };
620
+ const resolve = (id, response) => {
621
+ const fn = get$1(id);
622
+ if (!fn) {
623
+ console.log(response);
624
+ warn(`callback ${id} may already be disposed`);
625
+ return;
626
+ }
627
+ fn(response);
628
+ remove$1(id);
629
+ };
632
630
  const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
633
631
  const getErrorType = prettyError => {
634
632
  if (prettyError && prettyError.type) {
@@ -798,6 +796,8 @@ const execute = (command, ...args) => {
798
796
 
799
797
  const createRpc = ipc => {
800
798
  const rpc = {
799
+ // @ts-ignore
800
+ ipc,
801
801
  /**
802
802
  * @deprecated
803
803
  */
@@ -824,7 +824,8 @@ const logError = () => {
824
824
  };
825
825
  const handleMessage = event => {
826
826
  const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
827
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, actualRequiresSocket);
827
+ const actualExecute = event?.target?.execute || execute;
828
+ return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
828
829
  };
829
830
  const handleIpc = ipc => {
830
831
  if ('addEventListener' in ipc) {
@@ -958,7 +959,7 @@ const computeExplorerRenamedDirent = (dirents, index, newName) => {
958
959
  if (dirent.depth < depth) {
959
960
  break;
960
961
  }
961
- if (insertIndex === -1 && compareDirent(dirent, newDirent === -1)) {
962
+ if (insertIndex === -1 && compareDirent(dirent, newDirent) === -1) {
962
963
  for (; endIndex < dirents.length; endIndex++) {
963
964
  }
964
965
  insertIndex = endIndex;
@@ -1009,17 +1010,20 @@ const CreateFile = 1;
1009
1010
  const CreateFolder = 2;
1010
1011
  const Rename$1 = 3;
1011
1012
 
1012
- const state = {
1013
- rpc: undefined
1013
+ const RendererWorker = 1;
1014
+
1015
+ const rpcs = Object.create(null);
1016
+ const set = (id, rpc) => {
1017
+ rpcs[id] = rpc;
1018
+ };
1019
+ const get = id => {
1020
+ return rpcs[id];
1014
1021
  };
1022
+
1015
1023
  const invoke = (method, ...params) => {
1016
- const rpc = state.rpc;
1017
- // @ts-ignore
1024
+ const rpc = get(RendererWorker);
1018
1025
  return rpc.invoke(method, ...params);
1019
1026
  };
1020
- const setRpc = rpc => {
1021
- state.rpc = rpc;
1022
- };
1023
1027
 
1024
1028
  const remove = async dirent => {
1025
1029
  return invoke('FileSystem.remove', dirent);
@@ -1128,15 +1132,21 @@ const acceptCreate = async (state, newDirentType, createFn) => {
1128
1132
  deltaPosInSet = 1 - 1;
1129
1133
  break;
1130
1134
  } else {
1135
+ // @ts-ignore
1131
1136
  posInSet = dirent.posInSet + 1;
1137
+ // @ts-ignore
1132
1138
  setSize = dirent.setSize + 1;
1139
+ // @ts-ignore
1133
1140
  insertIndex = i;
1134
1141
  }
1142
+ // @ts-ignore
1135
1143
  dirent.setSize++;
1144
+ // @ts-ignore
1136
1145
  dirent.posInSet += deltaPosInSet;
1137
1146
  }
1138
1147
  newDirent.setSize = setSize;
1139
1148
  newDirent.posInSet = posInSet;
1149
+ // @ts-ignore
1140
1150
  items.splice(insertIndex + 1, 0, newDirent);
1141
1151
  const newDirents = [...items];
1142
1152
  const newMaxlineY = Math.max(state.maxLineY, newDirents.length);
@@ -1173,6 +1183,7 @@ const acceptRename = async state => {
1173
1183
  focusedIndex
1174
1184
  } = computeExplorerRenamedDirent(items, editingIndex, editingValue);
1175
1185
  // TODO move focused index
1186
+ // @ts-ignore
1176
1187
  state.items = newDirents;
1177
1188
  return {
1178
1189
  ...state,
@@ -1184,7 +1195,7 @@ const acceptRename = async state => {
1184
1195
  focused: true
1185
1196
  };
1186
1197
  };
1187
- const acceptEdit = state => {
1198
+ const acceptEdit = async state => {
1188
1199
  const {
1189
1200
  editingType
1190
1201
  } = state;
@@ -1218,11 +1229,6 @@ const isTopLevel$1 = dirent => {
1218
1229
  return dirent.depth === 1;
1219
1230
  };
1220
1231
 
1221
- const IsTopLevel = {
1222
- __proto__: null,
1223
- isTopLevel: isTopLevel$1
1224
- };
1225
-
1226
1232
  const toCollapsedDirent = dirent => {
1227
1233
  if (dirent.type === DirectoryExpanded) {
1228
1234
  return {
@@ -1237,7 +1243,7 @@ const collapseAll$1 = state => {
1237
1243
  const {
1238
1244
  items
1239
1245
  } = state;
1240
- const newDirents = items.filter(IsTopLevel).map(toCollapsedDirent);
1246
+ const newDirents = items.filter(isTopLevel$1).map(toCollapsedDirent);
1241
1247
  return {
1242
1248
  ...state,
1243
1249
  items: newDirents
@@ -1422,6 +1428,7 @@ const expandAll = async state => {
1422
1428
  if (dirent.depth === depth && dirent.type === Directory) {
1423
1429
  // TODO expand
1424
1430
  // TODO avoid mutating state here
1431
+ // @ts-ignore
1425
1432
  dirent.type = DirectoryExpanding;
1426
1433
  // TODO handle error
1427
1434
  // TODO race condition
@@ -1432,6 +1439,7 @@ const expandAll = async state => {
1432
1439
  }
1433
1440
  newDirents.splice(newIndex + 1, 0, ...childDirents);
1434
1441
  // TODO avoid mutating state here
1442
+ // @ts-ignore
1435
1443
  dirent.type = DirectoryExpanded;
1436
1444
  // await expand(state, dirent.index)
1437
1445
  }
@@ -1503,6 +1511,7 @@ const expandRecursively = async state => {
1503
1511
  // TODO race condition: what if folder is being collapse while it is recursively expanding?
1504
1512
  // TODO race condition: what if folder is being deleted while it is recursively expanding?
1505
1513
  // TODO race condition: what if a new file/folder is created while the folder is recursively expanding?
1514
+ // @ts-ignore
1506
1515
  const childDirents = await getChildDirentsRecursively(dirent);
1507
1516
  const startIndex = focusedIndex;
1508
1517
  if (focusedIndex >= 0) {
@@ -1621,11 +1630,6 @@ const focusPrevious = state => {
1621
1630
 
1622
1631
  const Button$2 = 1;
1623
1632
 
1624
- const CollapseAll = 'CollapseAll';
1625
- const NewFile$1 = 'NewFile';
1626
- const NewFolder$1 = 'NewFolder';
1627
- const Refresh = 'Refresh';
1628
-
1629
1633
  const emptyObject = {};
1630
1634
  const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1631
1635
  const i18nString = (key, placeholders = emptyObject) => {
@@ -1638,8 +1642,8 @@ const i18nString = (key, placeholders = emptyObject) => {
1638
1642
  return key.replaceAll(RE_PLACEHOLDER, replacer);
1639
1643
  };
1640
1644
 
1641
- const NewFile = 'New File...';
1642
- const NewFolder = 'New Folder...';
1645
+ const NewFile$1 = 'New File...';
1646
+ const NewFolder$1 = 'New Folder...';
1643
1647
  const OpenContainingFolder = 'Open Containing Folder';
1644
1648
  const OpenInIntegratedTerminal = 'Open in integrated Terminal';
1645
1649
  const Cut$1 = 'Cut';
@@ -1656,10 +1660,10 @@ const YouHaveNotYetOpenedAFolder = 'You have not yet opened a folder';
1656
1660
  const OpenFolder = 'Open folder';
1657
1661
 
1658
1662
  const newFile$1 = () => {
1659
- return i18nString(NewFile);
1663
+ return i18nString(NewFile$1);
1660
1664
  };
1661
1665
  const newFolder$1 = () => {
1662
- return i18nString(NewFolder);
1666
+ return i18nString(NewFolder$1);
1663
1667
  };
1664
1668
  const openContainingFolder$1 = () => {
1665
1669
  return i18nString(OpenContainingFolder);
@@ -1704,6 +1708,11 @@ const openFolder$1 = () => {
1704
1708
  return i18nString(OpenFolder);
1705
1709
  };
1706
1710
 
1711
+ const CollapseAll = 'CollapseAll';
1712
+ const NewFile = 'NewFile';
1713
+ const NewFolder = 'NewFolder';
1714
+ const Refresh = 'Refresh';
1715
+
1707
1716
  const getActions = root => {
1708
1717
  if (!root) {
1709
1718
  return [];
@@ -1711,12 +1720,12 @@ const getActions = root => {
1711
1720
  return [{
1712
1721
  type: Button$2,
1713
1722
  id: newFile$1(),
1714
- icon: NewFile$1,
1723
+ icon: NewFile,
1715
1724
  command: 'newFile'
1716
1725
  }, {
1717
1726
  type: Button$2,
1718
1727
  id: newFolder$1(),
1719
- icon: NewFolder$1,
1728
+ icon: NewFolder,
1720
1729
  command: 'newFolder'
1721
1730
  }, {
1722
1731
  type: Button$2,
@@ -1739,6 +1748,7 @@ const TreeItem$1 = 'treeitem';
1739
1748
  const Actions = 'Actions';
1740
1749
  const Button$1 = 'Button';
1741
1750
  const ButtonPrimary = 'ButtonPrimary';
1751
+ const Chevron = 'Chevron';
1742
1752
  const Explorer$1 = 'Explorer';
1743
1753
  const FileIcon = 'FileIcon';
1744
1754
  const IconButton = 'IconButton';
@@ -1775,11 +1785,6 @@ const getFileIconVirtualDom = icon => {
1775
1785
  };
1776
1786
  };
1777
1787
 
1778
- const defaultIndent = 1;
1779
- const getTreeItemIndent = depth => {
1780
- return `${depth * defaultIndent}rem`;
1781
- };
1782
-
1783
1788
  const ExplorerInput = 'ExploreerInput';
1784
1789
 
1785
1790
  const text = data => {
@@ -1799,8 +1804,11 @@ const getItemVirtualDomFile = item => {
1799
1804
  path,
1800
1805
  depth,
1801
1806
  isFocused,
1802
- isEditing
1807
+ isEditing,
1808
+ indent
1803
1809
  } = item;
1810
+
1811
+ // TODO avoid mutation
1804
1812
  const dom = [];
1805
1813
  dom.push({
1806
1814
  type: Div,
@@ -1812,7 +1820,7 @@ const getItemVirtualDomFile = item => {
1812
1820
  ariaSetSize: setSize,
1813
1821
  ariaLevel: depth,
1814
1822
  childCount: 2,
1815
- paddingLeft: getTreeItemIndent(depth),
1823
+ paddingLeft: indent,
1816
1824
  ariaLabel: name,
1817
1825
  ariaDescription: ''
1818
1826
  }, getFileIconVirtualDom(icon));
@@ -1840,6 +1848,22 @@ const getItemVirtualDomFile = item => {
1840
1848
  }
1841
1849
  return dom;
1842
1850
  };
1851
+
1852
+ const getChevronDownVirtualDom = () => {
1853
+ return {
1854
+ type: Div,
1855
+ className: `${Chevron} MaskIconChevronDown`,
1856
+ childCount: 0
1857
+ };
1858
+ };
1859
+ const getChevronRightVirtualDom = () => {
1860
+ return {
1861
+ type: Div,
1862
+ className: `${Chevron} MaskIconChevronRight`,
1863
+ childCount: 0
1864
+ };
1865
+ };
1866
+
1843
1867
  const getItemVirtualDomFolder = item => {
1844
1868
  const {
1845
1869
  posInSet,
@@ -1849,19 +1873,25 @@ const getItemVirtualDomFolder = item => {
1849
1873
  path,
1850
1874
  depth,
1851
1875
  type,
1852
- isFocused
1876
+ isFocused,
1877
+ useChevrons,
1878
+ indent
1853
1879
  } = item;
1854
1880
  let ariaExpanded = '';
1881
+ let chevron;
1855
1882
  switch (type) {
1856
1883
  // TODO decide on directory vs folder
1857
1884
  case Directory:
1858
1885
  ariaExpanded = 'false';
1886
+ chevron = getChevronRightVirtualDom();
1859
1887
  break;
1860
1888
  case DirectoryExpanding:
1861
1889
  ariaExpanded = 'true'; // TODO tree should be aria-busy then
1890
+ chevron = getChevronRightVirtualDom();
1862
1891
  break;
1863
1892
  case DirectoryExpanded:
1864
1893
  ariaExpanded = 'true';
1894
+ chevron = getChevronDownVirtualDom();
1865
1895
  break;
1866
1896
  }
1867
1897
  const dom = [];
@@ -1875,11 +1905,17 @@ const getItemVirtualDomFolder = item => {
1875
1905
  ariaSetSize: setSize,
1876
1906
  ariaLevel: depth,
1877
1907
  childCount: 2,
1878
- paddingLeft: getTreeItemIndent(depth),
1908
+ paddingLeft: indent,
1879
1909
  ariaLabel: name,
1880
1910
  ariaExpanded,
1881
1911
  ariaDescription: ''
1882
1912
  });
1913
+ if (useChevrons) {
1914
+ // @ts-ignore
1915
+ dom[0].childCount++;
1916
+ // @ts-ignore
1917
+ dom.push(chevron);
1918
+ }
1883
1919
  dom.push(getFileIconVirtualDom(icon), {
1884
1920
  type: Div,
1885
1921
  className: Label,
@@ -1891,6 +1927,7 @@ const getItemVirtualDomFolder = item => {
1891
1927
  }
1892
1928
  return dom;
1893
1929
  };
1930
+
1894
1931
  const getExplorerItemVirtualDom = item => {
1895
1932
  const {
1896
1933
  type
@@ -1935,6 +1972,7 @@ const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide) => {
1935
1972
  if (!root) {
1936
1973
  return getExplorerWelcomeVirtualDom(isWide);
1937
1974
  }
1975
+ // TODO
1938
1976
  const dom = [];
1939
1977
  dom.push({
1940
1978
  type: Div,
@@ -2167,24 +2205,35 @@ const getMenuEntries = state => {
2167
2205
  }
2168
2206
  };
2169
2207
 
2170
- const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, icons) => {
2208
+ const defaultIndent = 1;
2209
+ const getTreeItemIndent = depth => {
2210
+ // TODO logic should be in getVisibleItems
2211
+ return `${depth * defaultIndent}rem`;
2212
+ };
2213
+
2214
+ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, icons, useChevrons) => {
2171
2215
  const visible = [];
2172
2216
  let iconIndex = 0;
2173
2217
  for (let i = minLineY; i < Math.min(maxLineY, items.length); i++) {
2174
2218
  const item = items[i];
2175
2219
  const icon = icons[iconIndex++];
2220
+ const indent = getTreeItemIndent(item.depth);
2176
2221
  if (i === editingIndex) {
2177
2222
  visible.push({
2178
2223
  ...item,
2179
2224
  isFocused: i === focusedIndex,
2180
2225
  isEditing: true,
2181
- icon
2226
+ icon,
2227
+ useChevrons,
2228
+ indent
2182
2229
  });
2183
2230
  } else {
2184
2231
  visible.push({
2185
2232
  ...item,
2186
2233
  isFocused: i === focusedIndex,
2187
- icon
2234
+ icon,
2235
+ useChevrons,
2236
+ indent
2188
2237
  });
2189
2238
  }
2190
2239
  }
@@ -2198,7 +2247,9 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
2198
2247
  name: 'new',
2199
2248
  path: '/test/new',
2200
2249
  type: 2,
2201
- isEditing: true
2250
+ isEditing: true,
2251
+ useChevrons,
2252
+ indent: ''
2202
2253
  });
2203
2254
  }
2204
2255
  return visible;
@@ -2315,7 +2366,7 @@ const handleClickDirectoryExpanded$1 = async (state, dirent, index, keepFocus) =
2315
2366
  };
2316
2367
  };
2317
2368
 
2318
- const handleClickDirectoryExpanding = (state, dirent, index, keepFocus) => {
2369
+ const handleClickDirectoryExpanding = async (state, dirent, index, keepFocus) => {
2319
2370
  dirent.type = Directory;
2320
2371
  dirent.icon = getIcon();
2321
2372
  return {
@@ -2500,7 +2551,7 @@ const handleClickDirectoryExpanded = (state, dirent, index, keepFocus) => {
2500
2551
  focused: keepFocus
2501
2552
  };
2502
2553
  };
2503
- const handleClick = (state, index, keepFocus = false) => {
2554
+ const handleClick = async (state, index, keepFocus = false) => {
2504
2555
  const {
2505
2556
  items,
2506
2557
  minLineY
@@ -2552,6 +2603,7 @@ const handleArrowRightDirectoryExpanded = (state, dirent) => {
2552
2603
  if (nextDirent.depth === dirent.depth + 1) {
2553
2604
  return focusIndex(state, focusedIndex + 1);
2554
2605
  }
2606
+ return state;
2555
2607
  };
2556
2608
  const handleArrowRight = async state => {
2557
2609
  const {
@@ -2669,7 +2721,7 @@ const handleCopy = async state => {
2669
2721
  const dirent = getFocusedDirent$1(state);
2670
2722
  if (!dirent) {
2671
2723
  console.info('[ViewletExplorer/handleCopy] no dirent selected');
2672
- return;
2724
+ return state;
2673
2725
  }
2674
2726
  const absolutePath = dirent.path;
2675
2727
  // TODO handle copy error gracefully
@@ -2737,23 +2789,13 @@ const handleDragOver = (state, x, y) => {
2737
2789
  };
2738
2790
  };
2739
2791
 
2740
- const getFilePathElectron = async file => {
2741
- return invoke('GetFilePathElectron.getFilePathElectron', file);
2792
+ const uploadFileSystemHandles = async (root, pathSeparator, fileSystemHandles) => {
2793
+ // TODO send to renderer worker
2742
2794
  };
2743
2795
 
2744
2796
  const mergeDirents$2 = (oldDirents, newDirents) => {
2745
2797
  return newDirents;
2746
2798
  };
2747
-
2748
- // TODO copy files in parallel
2749
- const copyFilesElectron = async (root, pathSeparator, files) => {
2750
- for (const file of files) {
2751
- const from = await getFilePathElectron(file);
2752
- // const from = file.path
2753
- const to = join(pathSeparator, root, file.name);
2754
- await copy$1(from, to);
2755
- }
2756
- };
2757
2799
  const getMergedDirents$2 = async (root, pathSeparator, dirents) => {
2758
2800
  const childDirents = await getChildDirents(pathSeparator, {
2759
2801
  path: root,
@@ -2768,7 +2810,10 @@ const handleDrop$2 = async (state, files) => {
2768
2810
  pathSeparator,
2769
2811
  items
2770
2812
  } = state;
2771
- await copyFilesElectron(root, pathSeparator, files);
2813
+ const handled = await uploadFileSystemHandles();
2814
+ if (handled) {
2815
+ return state;
2816
+ }
2772
2817
  const mergedDirents = await getMergedDirents$2(root, pathSeparator, items);
2773
2818
  return {
2774
2819
  ...state,
@@ -2777,13 +2822,23 @@ const handleDrop$2 = async (state, files) => {
2777
2822
  };
2778
2823
  };
2779
2824
 
2780
- const uploadFileSystemHandles = async (root, pathSeparator, fileSystemHandles) => {
2781
- // TODO send to renderer worker
2825
+ const getFilePathElectron = async file => {
2826
+ return invoke('GetFilePathElectron.getFilePathElectron', file);
2782
2827
  };
2783
2828
 
2784
2829
  const mergeDirents$1 = (oldDirents, newDirents) => {
2785
2830
  return newDirents;
2786
2831
  };
2832
+
2833
+ // TODO copy files in parallel
2834
+ const copyFilesElectron = async (root, pathSeparator, files) => {
2835
+ for (const file of files) {
2836
+ const from = await getFilePathElectron(file);
2837
+ // const from = file.path
2838
+ const to = join(pathSeparator, root, file.name);
2839
+ await copy$1(from, to);
2840
+ }
2841
+ };
2787
2842
  const getMergedDirents$1 = async (root, pathSeparator, dirents) => {
2788
2843
  const childDirents = await getChildDirents(pathSeparator, {
2789
2844
  path: root,
@@ -2798,10 +2853,7 @@ const handleDrop$1 = async (state, files) => {
2798
2853
  pathSeparator,
2799
2854
  items
2800
2855
  } = state;
2801
- const handled = await uploadFileSystemHandles();
2802
- if (handled) {
2803
- return state;
2804
- }
2856
+ await copyFilesElectron(root, pathSeparator, files);
2805
2857
  const mergedDirents = await getMergedDirents$1(root, pathSeparator, items);
2806
2858
  return {
2807
2859
  ...state,
@@ -2812,11 +2864,12 @@ const handleDrop$1 = async (state, files) => {
2812
2864
 
2813
2865
  const getModule = isElectron => {
2814
2866
  if (isElectron) {
2815
- return handleDrop$2;
2867
+ return handleDrop$1;
2816
2868
  }
2817
- return handleDrop$1;
2869
+ return handleDrop$2;
2818
2870
  };
2819
2871
  const handleDropRoot = async (state, files) => {
2872
+ // @ts-ignore
2820
2873
  const fn = await getModule(state.isElectron);
2821
2874
  return fn(state, files);
2822
2875
  };
@@ -2869,7 +2922,7 @@ const handleDropIntoFile = (state, dirent, index, files) => {
2869
2922
  // @ts-ignore
2870
2923
  return handleDropIndex(parentIndex);
2871
2924
  };
2872
- const handleDropIndex = (state, index, files) => {
2925
+ const handleDropIndex = async (state, index, files) => {
2873
2926
  const {
2874
2927
  items
2875
2928
  } = state;
@@ -2968,6 +3021,7 @@ const handlePasteCopy = async (state, nativeFiles) => {
2968
3021
  // TODO handle pasting files into hardlink
2969
3022
  // TODO what if folder is big and it takes a long time
2970
3023
  for (const source of nativeFiles.files) {
3024
+ // @ts-ignore
2971
3025
  const target = join(state.pathSeperator, state.root, getBaseName(state.pathSeparator, source));
2972
3026
  await copy$1(source, target);
2973
3027
  }
@@ -2983,7 +3037,7 @@ const handlePasteCut = async (state, nativeFiles) => {
2983
3037
  return state;
2984
3038
  };
2985
3039
 
2986
- const handlePasteNone = (state, nativeFiles) => {
3040
+ const handlePasteNone = async (state, nativeFiles) => {
2987
3041
  console.info('[ViewletExplorer/handlePaste] no paths detected');
2988
3042
  return state;
2989
3043
  };
@@ -3189,6 +3243,7 @@ const getSavedRoot$1 = (savedState, workspacePath) => {
3189
3243
  return workspacePath;
3190
3244
  };
3191
3245
  const loadContent = async (state, savedState) => {
3246
+ const useChevrons = true;
3192
3247
  const workspacePath = await getWorkspacePath();
3193
3248
  const root = getSavedRoot$1(savedState, workspacePath);
3194
3249
  // TODO path separator could be restored from saved state
@@ -3218,7 +3273,8 @@ const loadContent = async (state, savedState) => {
3218
3273
  deltaY,
3219
3274
  maxLineY,
3220
3275
  pathSeparator,
3221
- excluded
3276
+ excluded,
3277
+ useChevrons
3222
3278
  };
3223
3279
  };
3224
3280
 
@@ -3232,12 +3288,12 @@ const handleWorkspaceChange = async state => {
3232
3288
  return newState;
3233
3289
  };
3234
3290
 
3235
- const ExplorerEditBox = FocusExplorerEditBox;
3236
-
3237
3291
  const setFocus = key => {
3238
3292
  return invoke('Focus.setFocus', key);
3239
3293
  };
3240
3294
 
3295
+ const ExplorerEditBox = FocusExplorerEditBox;
3296
+
3241
3297
  const newDirent = async (state, editingType) => {
3242
3298
  // TODO make focus functional instead of side effect
3243
3299
  await setFocus(ExplorerEditBox);
@@ -3309,12 +3365,14 @@ const removeDirent = async state => {
3309
3365
  // on web should probably show notification (dialog)
3310
3366
  // ErrorHandling.handleError(error)
3311
3367
  // await ErrorHandling.showErrorDialog(error)
3312
- return;
3368
+ return state;
3313
3369
  }
3314
3370
  // TODO avoid state mutation
3371
+ // @ts-ignore
3315
3372
  const newVersion = ++state.version;
3316
3373
  // TODO race condition
3317
3374
  // const newState = await loadContent(state:any)
3375
+ // @ts-ignore
3318
3376
  if (state.version !== newVersion || state.disposed) {
3319
3377
  return state;
3320
3378
  }
@@ -3348,6 +3406,7 @@ const removeDirent = async state => {
3348
3406
  return {
3349
3407
  ...state,
3350
3408
  items: newDirents,
3409
+ // @ts-ignore
3351
3410
  icons,
3352
3411
  focusedIndex: indexToFocus
3353
3412
  };
@@ -3373,7 +3432,11 @@ const renderItems = {
3373
3432
  return JSON.stringify(oldState.items) === JSON.stringify(newState.items) && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex && oldState.editingIndex === newState.editingIndex && oldState.editingType === newState.editingType && oldState.editingValue === newState.editingValue && oldState.width === newState.width;
3374
3433
  },
3375
3434
  apply(oldState, newState) {
3376
- const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.icons);
3435
+ const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue,
3436
+ // @ts-ignore
3437
+ newState.icons,
3438
+ // @ts-ignore
3439
+ newState.useChevrons);
3377
3440
  const isWide = newState.width > 450;
3378
3441
  const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide);
3379
3442
  return ['Viewlet.setDom2', dom];
@@ -3440,7 +3503,7 @@ const getActionButtonVirtualDom = action => {
3440
3503
  title: id,
3441
3504
  'data-command': command,
3442
3505
  childCount: 1
3443
- }, getIconVirtualDom(icon)];
3506
+ }, getIconVirtualDom(icon || '')];
3444
3507
  };
3445
3508
 
3446
3509
  const getActionVirtualDom = action => {
@@ -3833,7 +3896,7 @@ const listen = async () => {
3833
3896
  const rpc = await WebWorkerRpcClient.create({
3834
3897
  commandMap: commandMap
3835
3898
  });
3836
- setRpc(rpc);
3899
+ set(RendererWorker, rpc);
3837
3900
  };
3838
3901
 
3839
3902
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "description": "Explorer Worker",
5
5
  "main": "dist/explorerViewWorkerMain.js",
6
6
  "type": "module",