@lvce-editor/source-control-worker 1.1.0 → 1.3.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.
@@ -524,10 +524,10 @@ const create$4 = (method, params) => {
524
524
  };
525
525
  };
526
526
  const callbacks = Object.create(null);
527
- const set$1 = (id, fn) => {
527
+ const set$2 = (id, fn) => {
528
528
  callbacks[id] = fn;
529
529
  };
530
- const get$2 = id => {
530
+ const get$3 = id => {
531
531
  return callbacks[id];
532
532
  };
533
533
  const remove = id => {
@@ -543,7 +543,7 @@ const registerPromise = () => {
543
543
  resolve,
544
544
  promise
545
545
  } = Promise.withResolvers();
546
- set$1(id, resolve);
546
+ set$2(id, resolve);
547
547
  return {
548
548
  id,
549
549
  promise
@@ -700,7 +700,7 @@ const warn = (...args) => {
700
700
  console.warn(...args);
701
701
  };
702
702
  const resolve = (id, response) => {
703
- const fn = get$2(id);
703
+ const fn = get$3(id);
704
704
  if (!fn) {
705
705
  console.log(response);
706
706
  warn(`callback ${id} may already be disposed`);
@@ -739,7 +739,7 @@ const getErrorProperty = (error, prettyError) => {
739
739
  }
740
740
  };
741
741
  };
742
- const create$1 = (message, error) => {
742
+ const create$1$1 = (message, error) => {
743
743
  return {
744
744
  jsonrpc: Two,
745
745
  id: message.id,
@@ -750,7 +750,7 @@ const getErrorResponse = (message, error, preparePrettyError, logError) => {
750
750
  const prettyError = preparePrettyError(error);
751
751
  logError(error, prettyError);
752
752
  const errorProperty = getErrorProperty(error, prettyError);
753
- return create$1(message, errorProperty);
753
+ return create$1$1(message, errorProperty);
754
754
  };
755
755
  const create$5 = (message, result) => {
756
756
  return {
@@ -948,7 +948,7 @@ const MessagePortRpcParent = {
948
948
  __proto__: null,
949
949
  create: create$8
950
950
  };
951
- const create = async ({
951
+ const create$1 = async ({
952
952
  commandMap
953
953
  }) => {
954
954
  // TODO create a commandMap per rpc instance
@@ -960,24 +960,152 @@ const create = async ({
960
960
  };
961
961
  const WebWorkerRpcClient = {
962
962
  __proto__: null,
963
- create
963
+ create: create$1
964
964
  };
965
965
 
966
- const getPortTuple = () => {
967
- const {
968
- port1,
969
- port2
970
- } = new MessageChannel();
966
+ const create = () => {
967
+ const states = Object.create(null);
971
968
  return {
972
- port1,
973
- port2
969
+ get(uid) {
970
+ return states[uid];
971
+ },
972
+ set(uid, oldState, newState) {
973
+ states[uid] = {
974
+ oldState,
975
+ newState
976
+ };
977
+ },
978
+ dispose(uid) {
979
+ delete states[uid];
980
+ },
981
+ getKeys() {
982
+ return Object.keys(states).map(key => {
983
+ return Number.parseInt(key);
984
+ });
985
+ },
986
+ clear() {
987
+ for (const key of Object.keys(states)) {
988
+ delete states[key];
989
+ }
990
+ },
991
+ wrapCommand(fn) {
992
+ const wrapped = async (uid, ...args) => {
993
+ const {
994
+ newState
995
+ } = states[uid];
996
+ const newerState = await fn(newState, ...args);
997
+ if (newState === newerState) {
998
+ return;
999
+ }
1000
+ const latest = states[uid];
1001
+ states[uid] = {
1002
+ oldState: latest.oldState,
1003
+ newState: newerState
1004
+ };
1005
+ };
1006
+ return wrapped;
1007
+ },
1008
+ diff(uid, modules, numbers) {
1009
+ const {
1010
+ oldState,
1011
+ newState
1012
+ } = states[uid];
1013
+ const diffResult = [];
1014
+ for (let i = 0; i < modules.length; i++) {
1015
+ const fn = modules[i];
1016
+ if (!fn(oldState, newState)) {
1017
+ diffResult.push(numbers[i]);
1018
+ }
1019
+ }
1020
+ return diffResult;
1021
+ }
1022
+ };
1023
+ };
1024
+
1025
+ const {
1026
+ get: get$2,
1027
+ set: set$1,
1028
+ wrapCommand
1029
+ } = create();
1030
+
1031
+ const create2 = (id, uri, x, y, width, height, workspacePath) => {
1032
+ const state = {
1033
+ id,
1034
+ root: '',
1035
+ items: [],
1036
+ x,
1037
+ y,
1038
+ width,
1039
+ height,
1040
+ deltaY: 0,
1041
+ minLineY: 0,
1042
+ maxLineY: 0,
1043
+ fileIconCache: Object.create(null),
1044
+ icons: [],
1045
+ finalDeltaY: 0,
1046
+ handleOffset: 0,
1047
+ scrollBarActive: false,
1048
+ scrollBarHeight: 0,
1049
+ merge: [],
1050
+ index: [],
1051
+ untracked: [],
1052
+ workingTree: [],
1053
+ inputValue: '',
1054
+ displayItems: [],
1055
+ buttonIndex: -1,
1056
+ enabledProviderIds: [],
1057
+ isExpanded: true,
1058
+ buttons: [],
1059
+ providerId: '',
1060
+ splitButtonEnabled: false,
1061
+ allGroups: [],
1062
+ gitRoot: '',
1063
+ itemHeight: 20,
1064
+ minimumSliderSize: 20,
1065
+ workspacePath
974
1066
  };
1067
+ set$1(id, state, state);
1068
+ };
1069
+
1070
+ const RenderItems = 4;
1071
+
1072
+ const diffType = RenderItems;
1073
+ const isEqual = (oldState, newState) => {
1074
+ return oldState.allGroups === newState.allGroups && oldState.displayItems === newState.displayItems && oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.deltaY === newState.deltaY && oldState.buttonIndex === newState.buttonIndex && oldState.buttons === newState.buttons;
1075
+ };
1076
+
1077
+ const modules = [isEqual];
1078
+ const numbers = [diffType];
1079
+
1080
+ const diff = (oldState, newState) => {
1081
+ const diffResult = [];
1082
+ for (let i = 0; i < modules.length; i++) {
1083
+ const fn = modules[i];
1084
+ if (!fn(oldState, newState)) {
1085
+ diffResult.push(numbers[i]);
1086
+ }
1087
+ }
1088
+ return diffResult;
1089
+ };
1090
+
1091
+ const diff2 = uid => {
1092
+ const {
1093
+ oldState,
1094
+ newState
1095
+ } = get$2(uid);
1096
+ const result = diff(oldState, newState);
1097
+ return result;
1098
+ };
1099
+
1100
+ const commandIds = ['acceptInput', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusNone', 'focusPrevious', 'handleClick', 'handleClickAt', 'handleIconThemeChange', 'handleWheel'];
1101
+
1102
+ const getCommandIds = () => {
1103
+ return commandIds;
975
1104
  };
976
1105
 
977
1106
  const RendererWorker = 1;
978
1107
  const ExtensionHostWorker = 44;
979
1108
  const DebugWorker = 55;
980
- const SourceControlWorker = 66;
981
1109
 
982
1110
  const rpcs = Object.create(null);
983
1111
  const set = (id, rpc) => {
@@ -998,40 +1126,42 @@ const invokeAndTransfer = (method, ...params) => {
998
1126
  return rpc.invokeAndTransfer(method, ...params);
999
1127
  };
1000
1128
 
1001
- const sendMessagePortToExtensionHostWorker = async port => {
1002
- const command = 'HandleMessagePort.handleMessagePort';
1003
- await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, DebugWorker);
1129
+ const activateByEvent = event => {
1130
+ return invoke$1('ExtensionHostManagement.activateByEvent', event);
1004
1131
  };
1005
1132
 
1006
- const createExtensionHostRpc = async () => {
1007
- try {
1008
- const {
1009
- port1,
1010
- port2
1011
- } = getPortTuple();
1012
- await sendMessagePortToExtensionHostWorker(port2);
1013
- port1.start();
1014
- const rpc = await MessagePortRpcParent.create({
1015
- commandMap: {},
1016
- messagePort: port1,
1017
- isMessagePortOpen: false
1018
- });
1019
- // TODO createMessageportRpcParent should call port start
1020
- return rpc;
1021
- } catch (error) {
1022
- throw new VError(error, `Failed to create extension host rpc`);
1023
- }
1133
+ const invoke = async (method, ...params) => {
1134
+ const rpc = get$1(ExtensionHostWorker);
1135
+ return rpc.invoke(method, ...params);
1024
1136
  };
1025
1137
 
1026
- const initialize = async () => {
1027
- const extensionHostRpc = await createExtensionHostRpc();
1028
- set(SourceControlWorker, extensionHostRpc);
1138
+ const executeProvider = async ({
1139
+ event,
1140
+ method,
1141
+ params
1142
+ }) => {
1143
+ await activateByEvent(event);
1144
+ const result = await invoke(method, ...params);
1145
+ return result;
1146
+ };
1147
+
1148
+ const CommandExecute = 'ExtensionHostCommand.executeCommand';
1149
+ const SourceControlGetEnabledProviderIds = 'ExtensionHostSourceControl.getEnabledProviderIds';
1150
+ const SourceControlGetGroups = 'ExtensionHostSourceControl.getGroups';
1151
+
1152
+ const executeCommand = (id, ...args) => {
1153
+ return executeProvider({
1154
+ event: `onCommand:${id}`,
1155
+ method: CommandExecute,
1156
+ params: [id, ...args]
1157
+ });
1029
1158
  };
1030
1159
 
1160
+ const Directory = 3;
1031
1161
  const DirectoryExpanded = 4;
1032
1162
  const File = 7;
1033
1163
 
1034
- const getFileIcon = ({
1164
+ const getFileIcon$1 = ({
1035
1165
  name
1036
1166
  }) => {
1037
1167
  return '';
@@ -1088,7 +1218,7 @@ const getDisplayItemsGroup = (group, isExpanded) => {
1088
1218
  detail: folderName,
1089
1219
  posInSet: i + 1,
1090
1220
  setSize: length,
1091
- icon: getFileIcon({
1221
+ icon: getFileIcon$1({
1092
1222
  name: file
1093
1223
  }),
1094
1224
  decorationIcon: icon,
@@ -1102,6 +1232,7 @@ const getDisplayItemsGroup = (group, isExpanded) => {
1102
1232
  }
1103
1233
  return displayItems;
1104
1234
  };
1235
+
1105
1236
  const getDisplayItems = (allGroups, isExpanded) => {
1106
1237
  const displayItems = [];
1107
1238
  for (const group of allGroups) {
@@ -1111,12 +1242,121 @@ const getDisplayItems = (allGroups, isExpanded) => {
1111
1242
  return displayItems;
1112
1243
  };
1113
1244
 
1245
+ const getIconsCached = (dirents, fileIconCache) => {
1246
+ return dirents.map(dirent => fileIconCache[dirent]);
1247
+ };
1248
+
1249
+ const getMissingIconRequests = (dirents, fileIconCache) => {
1250
+ const missingRequests = [];
1251
+ for (const dirent of dirents) {
1252
+ if (!(dirent.file in fileIconCache)) {
1253
+ missingRequests.push({
1254
+ type: dirent.type,
1255
+ name: dirent.label,
1256
+ path: dirent.file
1257
+ });
1258
+ }
1259
+ }
1260
+ return missingRequests;
1261
+ };
1262
+
1263
+ const getPath = item => {
1264
+ return item.file;
1265
+ };
1266
+
1267
+ const getPaths = items => {
1268
+ return items.map(getPath);
1269
+ };
1270
+
1271
+ const getFileIcon = async name => {
1272
+ return invoke$1('IconTheme.getFileIcon', {
1273
+ name
1274
+ });
1275
+ };
1276
+
1277
+ const getFolderIcon = async name => {
1278
+ return invoke$1('IconTheme.getFolderIcon', {
1279
+ name
1280
+ });
1281
+ };
1282
+
1283
+ const requestFileIcons = async requests => {
1284
+ const promises = requests.map(request => request.type === File ? getFileIcon(request.name) : getFolderIcon(request.name));
1285
+ return Promise.all(promises);
1286
+ };
1287
+
1288
+ const updateIconCache = (iconCache, missingRequests, newIcons) => {
1289
+ if (missingRequests.length === 0) {
1290
+ return iconCache;
1291
+ }
1292
+ const newFileIconCache = {
1293
+ ...iconCache
1294
+ };
1295
+ for (let i = 0; i < missingRequests.length; i++) {
1296
+ const request = missingRequests[i];
1297
+ const icon = newIcons[i];
1298
+ newFileIconCache[request.path] = icon;
1299
+ }
1300
+ return newFileIconCache;
1301
+ };
1302
+
1303
+ const getFileIcons = async (dirents, fileIconCache) => {
1304
+ const missingRequests = getMissingIconRequests(dirents, fileIconCache);
1305
+ const newIcons = await requestFileIcons(missingRequests);
1306
+ const newFileIconCache = updateIconCache(fileIconCache, missingRequests, newIcons);
1307
+ const paths = getPaths(dirents);
1308
+ const icons = getIconsCached(paths, newFileIconCache);
1309
+ return {
1310
+ icons,
1311
+ newFileIconCache
1312
+ };
1313
+ };
1314
+
1114
1315
  const getFinalDeltaY = (height, itemHeight, itemsLength) => {
1115
1316
  const contentHeight = itemsLength * itemHeight;
1116
1317
  const finalDeltaY = Math.max(contentHeight - height, 0);
1117
1318
  return finalDeltaY;
1118
1319
  };
1119
1320
 
1321
+ const getGroups$2 = (providerId, path) => {
1322
+ return executeProvider({
1323
+ event: 'none',
1324
+ method: SourceControlGetGroups,
1325
+ params: [providerId, path]
1326
+ // noProviderFoundMessage: 'No source control provider found',
1327
+ });
1328
+ };
1329
+ const getEnabledProviderIds$1 = (scheme, root) => {
1330
+ return executeProvider({
1331
+ event: `onSourceControl:${scheme}`,
1332
+ method: SourceControlGetEnabledProviderIds,
1333
+ params: [scheme, root]
1334
+ // noProviderFoundMessage: 'No source control provider found',
1335
+ });
1336
+ };
1337
+
1338
+ const getEnabledProviderIds = (scheme, root) => {
1339
+ string(scheme);
1340
+ string(root);
1341
+ return getEnabledProviderIds$1(scheme, root);
1342
+ };
1343
+ const getGroups$1 = (providerId, root) => {
1344
+ return getGroups$2(providerId, root);
1345
+ };
1346
+
1347
+ const getGroups = async enabledProviderIds => {
1348
+ const allGroups = [];
1349
+ for (const providerId of enabledProviderIds) {
1350
+ // @ts-ignore
1351
+ const groups = await getGroups$1(providerId);
1352
+ allGroups.push(...groups);
1353
+ }
1354
+ return {
1355
+ allGroups,
1356
+ gitRoot: ''
1357
+ };
1358
+ };
1359
+
1120
1360
  const getListHeight = (itemsLength, itemHeight, maxHeight) => {
1121
1361
  number(itemsLength);
1122
1362
  number(itemHeight);
@@ -1160,54 +1400,6 @@ const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
1160
1400
  return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
1161
1401
  };
1162
1402
 
1163
- const activateByEvent = event => {
1164
- return invoke$1('ExtensionHostManagement.activateByEvent', event);
1165
- };
1166
-
1167
- const invoke = async (method, ...params) => {
1168
- const rpc = get$1(ExtensionHostWorker);
1169
- return rpc.invoke(method, ...params);
1170
- };
1171
-
1172
- const executeProvider = async ({
1173
- event,
1174
- method,
1175
- params
1176
- }) => {
1177
- await activateByEvent(event);
1178
- const result = await invoke(method, ...params);
1179
- return result;
1180
- };
1181
-
1182
- const SourceControlGetEnabledProviderIds = 'ExtensionHostSourceControl.getEnabledProviderIds';
1183
- const SourceControlGetGroups = 'ExtensionHostSourceControl.getGroups';
1184
-
1185
- const getGroups$2 = (providerId, path) => {
1186
- return executeProvider({
1187
- event: 'none',
1188
- method: SourceControlGetGroups,
1189
- params: [providerId, path]
1190
- // noProviderFoundMessage: 'No source control provider found',
1191
- });
1192
- };
1193
- const getEnabledProviderIds$1 = (scheme, root) => {
1194
- return executeProvider({
1195
- event: `onSourceControl:${scheme}`,
1196
- method: SourceControlGetEnabledProviderIds,
1197
- params: [scheme, root]
1198
- // noProviderFoundMessage: 'No source control provider found',
1199
- });
1200
- };
1201
-
1202
- const getEnabledProviderIds = (scheme, root) => {
1203
- string(scheme);
1204
- string(root);
1205
- return getEnabledProviderIds$1(scheme, root);
1206
- };
1207
- const getGroups$1 = (providerId, root) => {
1208
- return getGroups$2(providerId, root);
1209
- };
1210
-
1211
1403
  const getExtensions = async () => {
1212
1404
  return invoke('Extensions.getExtensions');
1213
1405
  };
@@ -1242,18 +1434,6 @@ const getSourceControlActions = async (providerId, groupId, type) => {
1242
1434
  return value;
1243
1435
  };
1244
1436
 
1245
- const getGroups = async enabledProviderIds => {
1246
- const allGroups = [];
1247
- for (const providerId of enabledProviderIds) {
1248
- // @ts-ignore
1249
- const groups = await getGroups$1(providerId);
1250
- allGroups.push(...groups);
1251
- }
1252
- return {
1253
- allGroups,
1254
- gitRoot: ''
1255
- };
1256
- };
1257
1437
  const getNewButtons = async (displayItems, providerId, buttonIndex) => {
1258
1438
  if (buttonIndex === -1) {
1259
1439
  return [];
@@ -1270,7 +1450,8 @@ const loadContent = async state => {
1270
1450
  itemHeight,
1271
1451
  height,
1272
1452
  minimumSliderSize,
1273
- workspacePath
1453
+ workspacePath,
1454
+ fileIconCache
1274
1455
  } = state;
1275
1456
  const root = workspacePath;
1276
1457
  const scheme = getProtocol(root);
@@ -1290,6 +1471,10 @@ const loadContent = async state => {
1290
1471
  const numberOfVisible = getNumberOfVisibleItems(listHeight, itemHeight);
1291
1472
  const maxLineY = Math.min(numberOfVisible, total);
1292
1473
  const finalDeltaY = getFinalDeltaY(listHeight, itemHeight, total);
1474
+ const {
1475
+ icons,
1476
+ newFileIconCache
1477
+ } = await getFileIcons(items, fileIconCache);
1293
1478
  return {
1294
1479
  ...state,
1295
1480
  allGroups,
@@ -1302,7 +1487,547 @@ const loadContent = async state => {
1302
1487
  splitButtonEnabled,
1303
1488
  maxLineY,
1304
1489
  scrollBarHeight,
1305
- finalDeltaY
1490
+ finalDeltaY,
1491
+ icons,
1492
+ fileIconCache: newFileIconCache
1493
+ };
1494
+ };
1495
+
1496
+ const handleButtonClick = async (state, clickedIndex) => {
1497
+ const {
1498
+ buttonIndex,
1499
+ buttons,
1500
+ items
1501
+ } = state;
1502
+ const button = buttons[clickedIndex];
1503
+ const item = items[buttonIndex];
1504
+ if (!button) {
1505
+ return state;
1506
+ }
1507
+ await executeCommand(button.command, item.file);
1508
+ const newState = await loadContent(state);
1509
+ return newState;
1510
+ };
1511
+
1512
+ const show = async (x, y, id, ...args) => {
1513
+ return invoke$1('ContextMenu.show', x, y, id, ...args);
1514
+ };
1515
+
1516
+ const SourceControl$1 = 22;
1517
+
1518
+ const handleContextMenu = async (state, button, x, y) => {
1519
+ await show(x, y, SourceControl$1);
1520
+ return state;
1521
+ };
1522
+
1523
+ const getPortTuple = () => {
1524
+ const {
1525
+ port1,
1526
+ port2
1527
+ } = new MessageChannel();
1528
+ return {
1529
+ port1,
1530
+ port2
1531
+ };
1532
+ };
1533
+
1534
+ const sendMessagePortToExtensionHostWorker = async port => {
1535
+ const command = 'HandleMessagePort.handleMessagePort';
1536
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, DebugWorker);
1537
+ };
1538
+
1539
+ const createExtensionHostRpc = async () => {
1540
+ try {
1541
+ const {
1542
+ port1,
1543
+ port2
1544
+ } = getPortTuple();
1545
+ await sendMessagePortToExtensionHostWorker(port2);
1546
+ port1.start();
1547
+ const rpc = await MessagePortRpcParent.create({
1548
+ commandMap: {},
1549
+ messagePort: port1,
1550
+ isMessagePortOpen: false
1551
+ });
1552
+ // TODO createMessageportRpcParent should call port start
1553
+ return rpc;
1554
+ } catch (error) {
1555
+ throw new VError(error, `Failed to create extension host rpc`);
1556
+ }
1557
+ };
1558
+
1559
+ const initialize = async () => {
1560
+ const extensionHostRpc = await createExtensionHostRpc();
1561
+ set(ExtensionHostWorker, extensionHostRpc);
1562
+ };
1563
+
1564
+ const Actions = 'Actions';
1565
+ const Chevron = 'Chevron';
1566
+ const ChevronRight = 'ChevronRight';
1567
+ const DecorationIcon = 'DecorationIcon';
1568
+ const FileIcon = 'FileIcon';
1569
+ const IconButton = 'IconButton';
1570
+ const InputBox = 'InputBox';
1571
+ const Label = 'Label';
1572
+ const LabelDetail = 'LabelDetail';
1573
+ const MaskIcon = 'MaskIcon';
1574
+ const MaskIconChevronDown = 'MaskIconChevronDown';
1575
+ const SourceControl = 'SourceControl';
1576
+ const SourceControlBadge = 'SourceControlBadge';
1577
+ const SourceControlButton = 'SourceControlButton';
1578
+ const SourceControlHeader = 'SourceControlHeader';
1579
+ const SourceControlItems = 'SourceControlItems';
1580
+ const SplitButton = 'SplitButton';
1581
+ const SplitButtonContent = 'SplitButtonContent';
1582
+ const SplitButtonContentDisabled = 'SplitButtonContentDisabled';
1583
+ const SplitButtonDisabled = 'SplitButtonDisabled';
1584
+ const SplitButtonDropDown = 'SplitButtonDropDown';
1585
+ const SplitButtonDropDownDisabled = 'SplitButtonDropDownDisabled';
1586
+ const SplitButtonSeparator = 'SplitButtonSeparator';
1587
+ const StrikeThrough = 'StrikeThrough';
1588
+ const TreeItem$1 = 'TreeItem';
1589
+ const Viewlet = 'Viewlet';
1590
+
1591
+ const HandleClick = 'handleClick';
1592
+ const HandleClickAt = 'handleClickAt';
1593
+ const HandleContextMenu = 'handleContextMenu';
1594
+ const HandleFocus = 'handleFocus';
1595
+ const HandleInput = 'handleInput';
1596
+ const HandleMouseOut = 'handleMouseOut';
1597
+ const HandleMouseOver = 'handleMouseOver';
1598
+ const HandleWheel = 'handleWheel';
1599
+
1600
+ const None = 'none';
1601
+ const ToolBar = 'toolbar';
1602
+ const Tree = 'tree';
1603
+ const TreeItem = 'treeitem';
1604
+
1605
+ const SourceControlInput$1 = 'SourceControlInput';
1606
+
1607
+ const emptyObject = {};
1608
+ const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1609
+ const i18nString = (key, placeholders = emptyObject) => {
1610
+ if (placeholders === emptyObject) {
1611
+ return key;
1612
+ }
1613
+ const replacer = (match, rest) => {
1614
+ return placeholders[rest];
1615
+ };
1616
+ return key.replaceAll(RE_PLACEHOLDER, replacer);
1617
+ };
1618
+
1619
+ const MessageEnterToCommitOnMaster = `Message (Enter) to commit on 'master'`;
1620
+ const SourceControlInput = 'Source Control Input';
1621
+
1622
+ const messageEnterToCommitOnMaster = () => {
1623
+ return i18nString(MessageEnterToCommitOnMaster);
1624
+ };
1625
+ const sourceControlInput = () => {
1626
+ return i18nString(SourceControlInput);
1627
+ };
1628
+
1629
+ const Button$1 = 1;
1630
+ const Div = 4;
1631
+ const Input = 6;
1632
+ const Span = 8;
1633
+ const Img = 17;
1634
+
1635
+ const getSourceControlHeaderVirtualDom = () => {
1636
+ return [{
1637
+ type: Div,
1638
+ className: SourceControlHeader,
1639
+ childCount: 1
1640
+ }, {
1641
+ type: Input,
1642
+ className: InputBox,
1643
+ ariaLabel: sourceControlInput(),
1644
+ autocapitalize: 'off',
1645
+ autocorrect: 'off',
1646
+ childCount: 0,
1647
+ name: SourceControlInput$1,
1648
+ onFocus: HandleFocus,
1649
+ onInput: HandleInput,
1650
+ placeholder: messageEnterToCommitOnMaster(),
1651
+ spellcheck: false
1652
+ }];
1653
+ };
1654
+
1655
+ const emptySourceControlButtons = [];
1656
+
1657
+ const getIconVirtualDom = (icon, type = Div) => {
1658
+ return {
1659
+ type,
1660
+ className: `MaskIcon MaskIcon${icon}`,
1661
+ role: None,
1662
+ childCount: 0
1663
+ };
1664
+ };
1665
+
1666
+ const addButtons = (dom, buttons) => {
1667
+ if (buttons === emptySourceControlButtons) {
1668
+ return;
1669
+ }
1670
+ dom[0].childCount += buttons.length;
1671
+ for (const button of buttons) {
1672
+ const {
1673
+ icon,
1674
+ label
1675
+ } = button;
1676
+ dom.push({
1677
+ type: Button$1,
1678
+ className: SourceControlButton,
1679
+ title: label,
1680
+ ariaLabel: label,
1681
+ childCount: 1
1682
+ }, getIconVirtualDom(icon, Span));
1683
+ }
1684
+ };
1685
+
1686
+ const mergeClassNames = (...classNames) => {
1687
+ return classNames.filter(Boolean).join(' ');
1688
+ };
1689
+ const Text = 12;
1690
+ const text = data => {
1691
+ return {
1692
+ type: Text,
1693
+ text: data,
1694
+ childCount: 0
1695
+ };
1696
+ };
1697
+
1698
+ const getBadgeVirtualDom = (className, count) => {
1699
+ return [{
1700
+ type: Div,
1701
+ className: `Badge ${className}`,
1702
+ childCount: 1
1703
+ }, text(`${count}`)];
1704
+ };
1705
+
1706
+ const getLabelClassName = decorationStrikeThrough => {
1707
+ let className = Label + ' Grow';
1708
+ if (decorationStrikeThrough) {
1709
+ className += ` ${StrikeThrough}`;
1710
+ }
1711
+ return className;
1712
+ };
1713
+
1714
+ const PaddingLeft = '1rem';
1715
+ const PaddingRight = '12px';
1716
+
1717
+ const createItemDirectory = item => {
1718
+ const {
1719
+ posInSet,
1720
+ setSize,
1721
+ icon,
1722
+ label,
1723
+ badgeCount,
1724
+ decorationStrikeThrough,
1725
+ type,
1726
+ buttons
1727
+ } = item;
1728
+ const labelClassName = getLabelClassName(decorationStrikeThrough);
1729
+ const dom = [{
1730
+ type: Div,
1731
+ className: TreeItem$1,
1732
+ role: TreeItem,
1733
+ ariaExpanded: type === DirectoryExpanded,
1734
+ ariaPosInSet: posInSet,
1735
+ ariaSetSize: setSize,
1736
+ childCount: 3,
1737
+ paddingLeft: PaddingLeft,
1738
+ paddingRight: PaddingRight
1739
+ }, {
1740
+ type: Div,
1741
+ className: `${Chevron} MaskIcon${icon}`,
1742
+ childCount: 0
1743
+ }, {
1744
+ type: Div,
1745
+ className: labelClassName,
1746
+ childCount: 1
1747
+ }, text(label)];
1748
+ addButtons(dom, buttons);
1749
+ dom.push(...getBadgeVirtualDom(SourceControlBadge, badgeCount));
1750
+ return dom;
1751
+ };
1752
+
1753
+ const getFileIconVirtualDom = icon => {
1754
+ return {
1755
+ type: Img,
1756
+ className: FileIcon,
1757
+ src: icon,
1758
+ role: None,
1759
+ childCount: 0
1760
+ };
1761
+ };
1762
+
1763
+ const chevron = {
1764
+ type: Div,
1765
+ className: Chevron,
1766
+ childCount: 1
1767
+ };
1768
+ const getIconsDom = (icon, fileIcon) => {
1769
+ if (icon === ChevronRight) {
1770
+ return [chevron, getIconVirtualDom(icon)];
1771
+ }
1772
+ return [getFileIconVirtualDom(fileIcon)];
1773
+ };
1774
+ const createItemOther = item => {
1775
+ const {
1776
+ posInSet,
1777
+ setSize,
1778
+ icon,
1779
+ file,
1780
+ label,
1781
+ decorationIcon,
1782
+ decorationIconTitle,
1783
+ decorationStrikeThrough,
1784
+ detail,
1785
+ buttons,
1786
+ fileIcon
1787
+ } = item;
1788
+ const labelClassName = getLabelClassName(decorationStrikeThrough);
1789
+ const dom = [];
1790
+ dom.push({
1791
+ type: Div,
1792
+ className: TreeItem$1,
1793
+ role: TreeItem,
1794
+ ariaPosInSet: posInSet,
1795
+ ariaSetSize: setSize,
1796
+ title: file,
1797
+ childCount: 3,
1798
+ paddingLeft: '1rem',
1799
+ paddingRight: '12px'
1800
+ }, ...getIconsDom(icon, fileIcon));
1801
+ const labelDom = {
1802
+ type: Div,
1803
+ className: labelClassName,
1804
+ childCount: 1
1805
+ };
1806
+ dom.push(labelDom, text(label));
1807
+ if (detail) {
1808
+ labelDom.childCount++;
1809
+ dom.push({
1810
+ type: Span,
1811
+ className: LabelDetail,
1812
+ childCount: 1
1813
+ }, text(detail));
1814
+ }
1815
+ addButtons(dom, buttons);
1816
+ dom.push({
1817
+ type: Img,
1818
+ className: DecorationIcon,
1819
+ title: decorationIconTitle,
1820
+ src: decorationIcon,
1821
+ childCount: 0
1822
+ });
1823
+ return dom;
1824
+ };
1825
+
1826
+ const getSourceControlItemVirtualDom = item => {
1827
+ switch (item.type) {
1828
+ case DirectoryExpanded:
1829
+ case Directory:
1830
+ return createItemDirectory(item);
1831
+ default:
1832
+ return createItemOther(item);
1833
+ }
1834
+ };
1835
+
1836
+ const getSourceControlItemsVirtualDom$1 = (hasItems, buttonText) => {
1837
+ const dom = [];
1838
+ dom.push({
1839
+ type: Div,
1840
+ className: `${SplitButton} ${hasItems ? '' : SplitButtonDisabled}`,
1841
+ childCount: 3
1842
+ }, {
1843
+ type: Div,
1844
+ className: `${SplitButtonContent} ${hasItems ? '' : SplitButtonContentDisabled}`,
1845
+ childCount: 1,
1846
+ tabIndex: 0
1847
+ }, text(buttonText), {
1848
+ type: Div,
1849
+ className: SplitButtonSeparator,
1850
+ childCount: 0
1851
+ }, {
1852
+ type: Div,
1853
+ className: `${SplitButtonDropDown} ${hasItems ? '' : SplitButtonDropDownDisabled}`,
1854
+ childCount: 1,
1855
+ tabIndex: 0
1856
+ }, {
1857
+ type: Div,
1858
+ className: `${MaskIcon} ${MaskIconChevronDown}`,
1859
+ childCount: 0
1860
+ });
1861
+ return dom;
1862
+ };
1863
+
1864
+ const getSourceControlItemsVirtualDom = (items, splitButtonEnabled) => {
1865
+ const dom = [];
1866
+ dom.push(...getSourceControlHeaderVirtualDom());
1867
+ if (splitButtonEnabled) {
1868
+ const hasItems = items.length > 0;
1869
+ dom.push(...getSourceControlItemsVirtualDom$1(hasItems, 'Commit'));
1870
+ }
1871
+ dom.push({
1872
+ type: Div,
1873
+ className: SourceControlItems,
1874
+ role: Tree,
1875
+ childCount: items.length
1876
+ }, ...items.flatMap(getSourceControlItemVirtualDom));
1877
+ return dom;
1878
+ };
1879
+
1880
+ const getSourceControlVirtualDom = (items, splitButtonEnabled) => {
1881
+ const dom = [{
1882
+ type: Div,
1883
+ className: mergeClassNames(Viewlet, SourceControl),
1884
+ tabIndex: 0,
1885
+ onClick: HandleClick,
1886
+ onContextMenu: HandleContextMenu,
1887
+ onMouseOver: HandleMouseOver,
1888
+ onMouseOut: HandleMouseOut,
1889
+ onWheel: HandleWheel,
1890
+ childCount: splitButtonEnabled ? 3 : 2
1891
+ }, ...getSourceControlItemsVirtualDom(items, splitButtonEnabled)];
1892
+ return dom;
1893
+ };
1894
+
1895
+ const getVisibleSourceControlItems = (items, minLineY, maxLineY, buttons, buttonIndex, icons) => {
1896
+ const visible = [];
1897
+ for (let i = minLineY; i < maxLineY; i++) {
1898
+ const item = items[i];
1899
+ const itemButtons = i === buttonIndex ? buttons : emptySourceControlButtons;
1900
+ const fileIcon = icons[i - minLineY];
1901
+ visible.push({
1902
+ ...item,
1903
+ buttons: itemButtons,
1904
+ fileIcon
1905
+ });
1906
+ }
1907
+ return visible;
1908
+ };
1909
+
1910
+ const renderItems = (oldState, newState) => {
1911
+ const visible = getVisibleSourceControlItems(newState.items, newState.minLineY, newState.maxLineY, newState.buttons, newState.buttonIndex, newState.icons);
1912
+ const dom = getSourceControlVirtualDom(visible, newState.splitButtonEnabled);
1913
+ return ['Viewlet.setDom2', dom];
1914
+ };
1915
+
1916
+ const getRenderer = diffType => {
1917
+ switch (diffType) {
1918
+ case RenderItems:
1919
+ return renderItems;
1920
+ default:
1921
+ throw new Error('unknown renderer');
1922
+ }
1923
+ };
1924
+
1925
+ const applyRender = (oldState, newState, diffResult) => {
1926
+ const commands = [];
1927
+ for (const item of diffResult) {
1928
+ const fn = getRenderer(item);
1929
+ const result = fn(oldState, newState);
1930
+ if (result.length > 0) {
1931
+ commands.push(result);
1932
+ }
1933
+ }
1934
+ return commands;
1935
+ };
1936
+
1937
+ const render2 = (uid, diffResult) => {
1938
+ const {
1939
+ oldState,
1940
+ newState
1941
+ } = get$2(uid);
1942
+ set$1(uid, newState, newState);
1943
+ const commands = applyRender(oldState, newState, diffResult);
1944
+ return commands;
1945
+ };
1946
+
1947
+ const Button = 1;
1948
+
1949
+ const getActionButtonVirtualDom = action => {
1950
+ const {
1951
+ id,
1952
+ icon,
1953
+ command
1954
+ } = action;
1955
+ return [{
1956
+ type: Button$1,
1957
+ className: IconButton,
1958
+ title: id,
1959
+ 'data-command': command,
1960
+ childCount: 1
1961
+ }, getIconVirtualDom(icon)];
1962
+ };
1963
+
1964
+ const getActionVirtualDom = action => {
1965
+ switch (action.type) {
1966
+ case Button:
1967
+ return getActionButtonVirtualDom(action);
1968
+ default:
1969
+ return [];
1970
+ }
1971
+ };
1972
+
1973
+ const getActionsVirtualDom = actions => {
1974
+ return [{
1975
+ type: Div,
1976
+ className: Actions,
1977
+ role: ToolBar,
1978
+ childCount: actions.length
1979
+ }, ...actions.flatMap(getActionVirtualDom)];
1980
+ };
1981
+
1982
+ const renderActions = uid => {
1983
+ const actions = [];
1984
+ const dom = getActionsVirtualDom(actions);
1985
+ return dom;
1986
+ };
1987
+
1988
+ const renderEventListeners = () => {
1989
+ return [{
1990
+ name: HandleWheel,
1991
+ params: ['handleWheel', 'event.deltaMode', 'event.deltaY'],
1992
+ passive: true
1993
+ }, {
1994
+ name: HandleFocus,
1995
+ params: ['handleFocus']
1996
+ }, {
1997
+ name: HandleClickAt,
1998
+ params: ['handleClickAt', 'event.clientX', 'event.clientY']
1999
+ }, {
2000
+ name: HandleMouseOver,
2001
+ params: ['handleMouseOver', 'event.clientX', 'event.clientY']
2002
+ }, {
2003
+ name: HandleInput,
2004
+ params: ['handleInput', 'event.target.value']
2005
+ }, {
2006
+ name: HandleContextMenu,
2007
+ params: ['handleContextMenu', 'event.button', 'event.clientX', 'event.clientY'],
2008
+ preventDefault: true
2009
+ }, {
2010
+ name: HandleWheel,
2011
+ params: ['handleWheel', 'event.deltaMode', 'event.deltaY'],
2012
+ passive: true
2013
+ }];
2014
+ };
2015
+
2016
+ const saveState = uid => {
2017
+ number(uid);
2018
+ const value = get$2(uid);
2019
+ const {
2020
+ newState
2021
+ } = value;
2022
+ const {
2023
+ root,
2024
+ maxLineY
2025
+ } = newState;
2026
+ return {
2027
+ root,
2028
+ minLineY: 0,
2029
+ maxLineY,
2030
+ deltaY: 0
1306
2031
  };
1307
2032
  };
1308
2033
 
@@ -1310,10 +2035,38 @@ const terminate = () => {
1310
2035
  globalThis.close();
1311
2036
  };
1312
2037
 
2038
+ const updateIcons = async state => {
2039
+ const {
2040
+ items,
2041
+ minLineY,
2042
+ maxLineY
2043
+ } = state;
2044
+ const visible = items.slice(minLineY, maxLineY);
2045
+ const {
2046
+ icons,
2047
+ newFileIconCache
2048
+ } = await getFileIcons(visible, Object.create(null));
2049
+ return {
2050
+ ...state,
2051
+ icons,
2052
+ fileIconCache: newFileIconCache
2053
+ };
2054
+ };
2055
+
1313
2056
  const commandMap = {
1314
2057
  'Initialize.initialize': initialize,
1315
- 'SourceControl.loadControl': loadContent,
1316
- 'SourceControl.terminate': terminate
2058
+ 'SourceControl.create2': create2,
2059
+ 'SourceControl.diff2': diff2,
2060
+ 'SourceControl.getCommandIds': getCommandIds,
2061
+ 'SourceControl.handleButtonClick': wrapCommand(handleButtonClick),
2062
+ 'SourceControl.handleContextMenu': wrapCommand(handleContextMenu),
2063
+ 'SourceControl.loadContent': wrapCommand(loadContent),
2064
+ 'SourceControl.render2': render2,
2065
+ 'SourceControl.renderActions2': renderActions,
2066
+ 'SourceControl.renderEventListeners': renderEventListeners,
2067
+ 'SourceControl.saveState': saveState,
2068
+ 'SourceControl.terminate': terminate,
2069
+ 'SourceControl.updateIcons': wrapCommand(updateIcons)
1317
2070
  };
1318
2071
 
1319
2072
  const listen = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/source-control-worker",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Source Control Worker",
5
5
  "keywords": [
6
6
  "Lvce Editor"