@lvce-editor/main-area-worker 3.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -102,14 +102,15 @@ const {
102
102
  get: get$2,
103
103
  getCommandIds,
104
104
  registerCommands,
105
- set: set$3,
105
+ set: set$4,
106
106
  wrapCommand,
107
107
  wrapGetter
108
108
  } = create$7();
109
109
 
110
- const create$6 = (uid, uri, x, y, width, height, platform, assetDir) => {
110
+ const create$6 = (uid, uri, x, y, width, height, platform, assetDir, tabHeight = 35) => {
111
111
  const state = {
112
112
  assetDir,
113
+ fileIconCache: {},
113
114
  height,
114
115
  layout: {
115
116
  activeGroupId: undefined,
@@ -117,12 +118,13 @@ const create$6 = (uid, uri, x, y, width, height, platform, assetDir) => {
117
118
  groups: []
118
119
  },
119
120
  platform,
121
+ tabHeight,
120
122
  uid,
121
123
  width,
122
124
  x,
123
125
  y
124
126
  };
125
- set$3(uid, state, state);
127
+ set$4(uid, state, state);
126
128
  };
127
129
 
128
130
  const isEqual = (oldState, newState) => {
@@ -154,14 +156,7 @@ const diff2 = uid => {
154
156
  return result;
155
157
  };
156
158
 
157
- const Button$1 = 1;
158
- const Div = 4;
159
- const Span = 8;
160
- const Text = 12;
161
- const Img = 17;
162
- const Pre = 51;
163
-
164
- const Button = 'event.button';
159
+ const Button$1 = 'event.button';
165
160
  const ClientX = 'event.clientX';
166
161
  const ClientY = 'event.clientY';
167
162
  const TargetName = 'event.target.name';
@@ -171,9 +166,6 @@ const Tab = 13;
171
166
  const Separator = 1;
172
167
  const None = 0;
173
168
 
174
- const ExtensionHostWorker = 44;
175
- const RendererWorker = 1;
176
-
177
169
  const SetDom2 = 'Viewlet.setDom2';
178
170
 
179
171
  const getMenuIds = () => {
@@ -187,6 +179,10 @@ const handleClick = async (state, name) => {
187
179
  return state;
188
180
  };
189
181
 
182
+ const ExtensionHostWorker = 44;
183
+ const IconThemeWorker = 7009;
184
+ const RendererWorker = 1;
185
+
190
186
  const normalizeLine = line => {
191
187
  if (line.startsWith('Error: ')) {
192
188
  return line.slice('Error: '.length);
@@ -1152,6 +1148,53 @@ const listen$1 = async (module, options) => {
1152
1148
  const ipc = module.wrap(rawIpc);
1153
1149
  return ipc;
1154
1150
  };
1151
+
1152
+ /* eslint-disable @typescript-eslint/no-misused-promises */
1153
+
1154
+ const createSharedLazyRpc = factory => {
1155
+ let rpcPromise;
1156
+ const getOrCreate = () => {
1157
+ if (!rpcPromise) {
1158
+ rpcPromise = factory();
1159
+ }
1160
+ return rpcPromise;
1161
+ };
1162
+ return {
1163
+ async dispose() {
1164
+ const rpc = await getOrCreate();
1165
+ await rpc.dispose();
1166
+ },
1167
+ async invoke(method, ...params) {
1168
+ const rpc = await getOrCreate();
1169
+ return rpc.invoke(method, ...params);
1170
+ },
1171
+ async invokeAndTransfer(method, ...params) {
1172
+ const rpc = await getOrCreate();
1173
+ return rpc.invokeAndTransfer(method, ...params);
1174
+ },
1175
+ async send(method, ...params) {
1176
+ const rpc = await getOrCreate();
1177
+ rpc.send(method, ...params);
1178
+ }
1179
+ };
1180
+ };
1181
+ const create$j = async ({
1182
+ commandMap,
1183
+ isMessagePortOpen,
1184
+ send
1185
+ }) => {
1186
+ return createSharedLazyRpc(() => {
1187
+ return create$3({
1188
+ commandMap,
1189
+ isMessagePortOpen,
1190
+ send
1191
+ });
1192
+ });
1193
+ };
1194
+ const LazyTransferMessagePortRpcParent = {
1195
+ __proto__: null,
1196
+ create: create$j
1197
+ };
1155
1198
  const create$5 = async ({
1156
1199
  commandMap,
1157
1200
  isMessagePortOpen = true,
@@ -1224,7 +1267,7 @@ const createMockRpc = ({
1224
1267
  };
1225
1268
 
1226
1269
  const rpcs = Object.create(null);
1227
- const set$2 = (id, rpc) => {
1270
+ const set$3 = (id, rpc) => {
1228
1271
  rpcs[id] = rpc;
1229
1272
  };
1230
1273
  const get = id => {
@@ -1257,7 +1300,7 @@ const create$1 = rpcId => {
1257
1300
  const mockRpc = createMockRpc({
1258
1301
  commandMap
1259
1302
  });
1260
- set$2(rpcId, mockRpc);
1303
+ set$3(rpcId, mockRpc);
1261
1304
  // @ts-ignore
1262
1305
  mockRpc[Symbol.dispose] = () => {
1263
1306
  remove(rpcId);
@@ -1266,15 +1309,24 @@ const create$1 = rpcId => {
1266
1309
  return mockRpc;
1267
1310
  },
1268
1311
  set(rpc) {
1269
- set$2(rpcId, rpc);
1312
+ set$3(rpcId, rpc);
1270
1313
  }
1271
1314
  };
1272
1315
  };
1273
1316
 
1274
1317
  const {
1275
- set: set$1
1318
+ set: set$2
1276
1319
  } = create$1(ExtensionHostWorker);
1277
1320
 
1321
+ const {
1322
+ invoke: invoke$1,
1323
+ set: set$1
1324
+ } = create$1(IconThemeWorker);
1325
+ const getIcons = async iconRequests => {
1326
+ // @ts-ignore
1327
+ return invoke$1('IconTheme.getIcons', iconRequests);
1328
+ };
1329
+
1278
1330
  const {
1279
1331
  invoke,
1280
1332
  invokeAndTransfer,
@@ -1288,6 +1340,11 @@ const showContextMenu2 = async (uid, menuId, x, y, args) => {
1288
1340
  // @ts-ignore
1289
1341
  await invoke('ContextMenu.show2', uid, menuId, x, y, args);
1290
1342
  };
1343
+ const sendMessagePortToIconThemeWorker = async (port, rpcId) => {
1344
+ const command = 'IconTheme.handleMessagePort';
1345
+ // @ts-ignore
1346
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToIconThemeWorker', port, command, rpcId);
1347
+ };
1291
1348
  const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
1292
1349
  const command = 'HandleMessagePort.handleMessagePort2';
1293
1350
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
@@ -1498,7 +1555,7 @@ const handleCreate = async command => {
1498
1555
  oldState
1499
1556
  } = get$2(command.uid);
1500
1557
  const readyState = handleViewletReady(state, command.editorUid);
1501
- set$3(command.uid, oldState, readyState);
1558
+ set$4(command.uid, oldState, readyState);
1502
1559
  return readyState;
1503
1560
  };
1504
1561
 
@@ -1624,6 +1681,30 @@ const handleClickCloseTab = (state, rawGroupIndex, rawIndex) => {
1624
1681
  return closeTab(state, groupId, tabId);
1625
1682
  };
1626
1683
 
1684
+ const createViewlet = async (viewletModuleId, editorUid, tabId, bounds, uri) => {
1685
+ // @ts-ignore
1686
+ await invoke('Layout.createViewlet', viewletModuleId, editorUid, tabId, bounds, uri);
1687
+ };
1688
+
1689
+ const findTabById = (state, tabId) => {
1690
+ const {
1691
+ layout
1692
+ } = state;
1693
+ const {
1694
+ groups
1695
+ } = layout;
1696
+ for (const group of groups) {
1697
+ const tab = group.tabs.find(t => t.id === tabId);
1698
+ if (tab) {
1699
+ return {
1700
+ groupId: group.id,
1701
+ tab
1702
+ };
1703
+ }
1704
+ }
1705
+ return undefined;
1706
+ };
1707
+
1627
1708
  // Counter for request IDs to handle race conditions
1628
1709
  let requestIdCounter = 0;
1629
1710
  const getNextRequestId = () => {
@@ -1635,7 +1716,7 @@ const startContentLoading = async (oldState, state, tabId, path, requestId) => {
1635
1716
  const getLatestState = () => {
1636
1717
  return get$2(state.uid).newState;
1637
1718
  };
1638
- set$3(state.uid, oldState, state);
1719
+ set$4(state.uid, oldState, state);
1639
1720
  const newState = await loadTabContentAsync(tabId, path, requestId, getLatestState);
1640
1721
  return newState;
1641
1722
  } catch {
@@ -1765,12 +1846,43 @@ const selectTab = async (state, groupIndex, index) => {
1765
1846
  };
1766
1847
  const createdState = createViewletForTab(newState, tabId, viewletModuleId, bounds);
1767
1848
  newState = createdState;
1849
+
1850
+ // Store updated state before creating viewlet
1851
+ set$4(uid, state, newState);
1852
+
1853
+ // Execute viewlet commands if any
1854
+ if (switchCommands.length > 0) {
1855
+ await executeViewletCommands(switchCommands);
1856
+ }
1857
+
1858
+ // Get the tab to extract editorUid for viewlet creation
1859
+ const tabWithViewlet = findTabById(newState, tabId);
1860
+ if (tabWithViewlet) {
1861
+ const {
1862
+ editorUid
1863
+ } = tabWithViewlet.tab;
1864
+ if (editorUid !== -1 && newTab.uri) {
1865
+ // Create the actual viewlet instance
1866
+ await createViewlet(viewletModuleId, editorUid, tabId, bounds, newTab.uri);
1867
+
1868
+ // Mark viewlet as ready
1869
+ newState = handleViewletReady(newState, editorUid);
1870
+ set$4(uid, state, newState);
1871
+ }
1872
+ }
1873
+
1874
+ // Start loading content in the background if needed
1875
+ if (needsLoading && tab.uri) {
1876
+ const latestState = await startContentLoading(state, newState, tabId, tab.uri, requestId);
1877
+ return latestState;
1878
+ }
1879
+ return newState;
1768
1880
  }
1769
1881
  } catch {
1770
1882
  // Viewlet creation is optional - silently ignore if RendererWorker isn't available
1771
1883
  }
1772
1884
  }
1773
- set$3(uid, state, newState);
1885
+ set$4(uid, state, newState);
1774
1886
 
1775
1887
  // Execute viewlet commands if any
1776
1888
  if (switchCommands.length > 0) {
@@ -1829,7 +1941,7 @@ const createExtensionHostRpc = async () => {
1829
1941
 
1830
1942
  const initialize = async () => {
1831
1943
  const rpc = await createExtensionHostRpc();
1832
- set$1(rpc);
1944
+ set$2(rpc);
1833
1945
  };
1834
1946
 
1835
1947
  const getMaxIdFromLayout = layout => {
@@ -1891,15 +2003,254 @@ const tryRestoreLayout = savedState => {
1891
2003
  return layout;
1892
2004
  };
1893
2005
 
2006
+ const getIconsCached = (dirents, fileIconCache) => {
2007
+ return dirents.map(dirent => fileIconCache[dirent]);
2008
+ };
2009
+
2010
+ const getBasename$1 = uri => {
2011
+ const lastSlashIndex = uri.lastIndexOf('/');
2012
+ if (lastSlashIndex === -1) {
2013
+ return uri;
2014
+ }
2015
+ return uri.slice(lastSlashIndex + 1);
2016
+ };
2017
+ const getMissingTabs = (tabs, fileIconCache) => {
2018
+ const missingTabs = [];
2019
+ for (const tab of tabs) {
2020
+ if (tab.uri && !(tab.uri in fileIconCache)) {
2021
+ missingTabs.push(tab);
2022
+ }
2023
+ }
2024
+ return missingTabs;
2025
+ };
2026
+ const tabToIconRequest = tab => {
2027
+ const uri = tab.uri || '';
2028
+ return {
2029
+ name: getBasename$1(uri),
2030
+ path: uri,
2031
+ type: 0 // file type
2032
+ };
2033
+ };
2034
+ const getMissingIconRequestsForTabs = (tabs, fileIconCache) => {
2035
+ const missingRequests = getMissingTabs(tabs, fileIconCache);
2036
+ const iconRequests = missingRequests.map(tabToIconRequest);
2037
+ return iconRequests;
2038
+ };
2039
+
2040
+ const Directory = 3;
2041
+ const DirectoryExpanded = 4;
2042
+
2043
+ const getSimpleIconRequestType = direntType => {
2044
+ if (direntType === Directory || direntType === DirectoryExpanded) {
2045
+ return 2;
2046
+ }
2047
+ return 1;
2048
+ };
2049
+
2050
+ const toSimpleIconRequest = request => {
2051
+ return {
2052
+ name: request.name,
2053
+ type: getSimpleIconRequestType(request.type)
2054
+ };
2055
+ };
2056
+
2057
+ const requestFileIcons = async requests => {
2058
+ if (requests.length === 0) {
2059
+ return [];
2060
+ }
2061
+ const simpleRequests = requests.map(toSimpleIconRequest);
2062
+ const icons = await getIcons(simpleRequests);
2063
+ return icons;
2064
+ };
2065
+
2066
+ const updateIconCache = (iconCache, missingRequests, newIcons) => {
2067
+ if (missingRequests.length === 0) {
2068
+ return iconCache;
2069
+ }
2070
+ const newFileIconCache = {
2071
+ ...iconCache
2072
+ };
2073
+ for (let i = 0; i < missingRequests.length; i++) {
2074
+ const request = missingRequests[i];
2075
+ const icon = newIcons[i];
2076
+ newFileIconCache[request.path] = icon;
2077
+ }
2078
+ return newFileIconCache;
2079
+ };
2080
+
2081
+ const getFileIconsForTabs = async (tabs, fileIconCache) => {
2082
+ const missingRequests = getMissingIconRequestsForTabs(tabs, fileIconCache);
2083
+ const newIcons = await requestFileIcons(missingRequests);
2084
+ const newFileIconCache = updateIconCache(fileIconCache, missingRequests, newIcons);
2085
+ const tabUris = tabs.map(tab => tab.uri || '');
2086
+ const icons = getIconsCached(tabUris, newFileIconCache);
2087
+ return {
2088
+ icons,
2089
+ newFileIconCache
2090
+ };
2091
+ };
2092
+
2093
+ const getAllTabs = layout => {
2094
+ const allTabs = [];
2095
+ for (const group of layout.groups) {
2096
+ allTabs.push(...group.tabs);
2097
+ }
2098
+ return allTabs;
2099
+ };
2100
+
2101
+ const loadFileIcons = async state => {
2102
+ try {
2103
+ const allTabs = getAllTabs(state.layout);
2104
+ const {
2105
+ newFileIconCache
2106
+ } = await getFileIconsForTabs(allTabs, state.fileIconCache);
2107
+
2108
+ // Update tabs with their icons
2109
+ const updatedLayout = {
2110
+ ...state.layout,
2111
+ groups: state.layout.groups.map(group => ({
2112
+ ...group,
2113
+ tabs: group.tabs.map(tab => ({
2114
+ ...tab,
2115
+ icon: newFileIconCache[tab.uri || '']
2116
+ }))
2117
+ }))
2118
+ };
2119
+ return {
2120
+ fileIconCache: newFileIconCache,
2121
+ updatedLayout
2122
+ };
2123
+ } catch {
2124
+ // If icon request fails, continue without icons
2125
+ return {
2126
+ fileIconCache: state.fileIconCache,
2127
+ updatedLayout: state.layout
2128
+ };
2129
+ }
2130
+ };
2131
+
2132
+ const getViewletModuleId = async uri => {
2133
+ // Query RendererWorker for viewlet module ID (optional, may fail in tests)
2134
+ let viewletModuleId;
2135
+ try {
2136
+ // @ts-ignore
2137
+ viewletModuleId = await invoke('Layout.getModuleId', uri);
2138
+ } catch {
2139
+ // Viewlet creation is optional - silently ignore if RendererWorker isn't available
2140
+ }
2141
+ return viewletModuleId;
2142
+ };
2143
+
2144
+ const TAB_HEIGHT = 35;
2145
+
2146
+ // Get viewlet module IDs for active tabs in each group
2147
+ const getViewletModuleIds = async layout => {
2148
+ const viewletModuleIds = {};
2149
+ for (const group of layout.groups) {
2150
+ const activeTab = group.tabs.find(tab => tab.id === group.activeTabId);
2151
+ if (activeTab && activeTab.uri) {
2152
+ const viewletModuleId = await getViewletModuleId(activeTab.uri);
2153
+ if (viewletModuleId) {
2154
+ viewletModuleIds[activeTab.id] = viewletModuleId;
2155
+ }
2156
+ }
2157
+ }
2158
+ return viewletModuleIds;
2159
+ };
2160
+
2161
+ // Create viewlets for the active tabs
2162
+ const createViewlets = async (layout, viewletModuleIds, bounds) => {
2163
+ const editorUids = {};
2164
+ for (const group of layout.groups) {
2165
+ const activeTab = group.tabs.find(tab => tab.id === group.activeTabId);
2166
+ if (activeTab && viewletModuleIds[activeTab.id]) {
2167
+ const editorUid = activeTab.editorUid === -1 ? create() : activeTab.editorUid;
2168
+ editorUids[activeTab.id] = editorUid;
2169
+ await createViewlet(viewletModuleIds[activeTab.id], editorUid, activeTab.id, bounds, activeTab.uri);
2170
+ }
2171
+ }
2172
+ return editorUids;
2173
+ };
2174
+
2175
+ // Update tabs with editor UIDs
2176
+ const updateTabs = (state, editorUids) => {
2177
+ const updatedGroups = state.layout.groups.map(group => {
2178
+ return {
2179
+ ...group,
2180
+ tabs: group.tabs.map(tab => {
2181
+ if (editorUids[tab.id]) {
2182
+ return {
2183
+ ...tab,
2184
+ editorUid: editorUids[tab.id]
2185
+ };
2186
+ }
2187
+ return tab;
2188
+ })
2189
+ };
2190
+ });
2191
+ return {
2192
+ ...state,
2193
+ layout: {
2194
+ ...state.layout,
2195
+ groups: updatedGroups
2196
+ }
2197
+ };
2198
+ };
2199
+ const restoreAndCreateEditors = async (state, restoredLayout) => {
2200
+ let newState = {
2201
+ ...state,
2202
+ layout: restoredLayout
2203
+ };
2204
+ const bounds = {
2205
+ height: newState.height - TAB_HEIGHT,
2206
+ width: newState.width,
2207
+ x: newState.x,
2208
+ y: newState.y + TAB_HEIGHT
2209
+ };
2210
+
2211
+ // Get viewlet module IDs for all active tabs
2212
+ const viewletModuleIds = await getViewletModuleIds(newState.layout);
2213
+
2214
+ // Create viewlets and get editor UIDs
2215
+ const editorUids = await createViewlets(newState.layout, viewletModuleIds, bounds);
2216
+
2217
+ // Update tabs with editor UIDs
2218
+ newState = updateTabs(newState, editorUids);
2219
+
2220
+ // Create viewlets in the lifecycle and mark them as ready
2221
+ for (const group of newState.layout.groups) {
2222
+ const activeTab = group.tabs.find(tab => tab.id === group.activeTabId);
2223
+ if (activeTab && viewletModuleIds[activeTab.id]) {
2224
+ const editorUid = editorUids[activeTab.id];
2225
+ newState = createViewletForTab(newState, activeTab.id);
2226
+ newState = handleViewletReady(newState, editorUid);
2227
+ }
2228
+ }
2229
+ return newState;
2230
+ };
2231
+
1894
2232
  const loadContent = async (state, savedState) => {
1895
2233
  const restoredLayout = tryRestoreLayout(savedState);
1896
2234
  if (restoredLayout) {
1897
2235
  const maxId = getMaxIdFromLayout(restoredLayout);
1898
2236
  setMinId(maxId);
1899
- return {
1900
- ...state,
1901
- layout: restoredLayout
2237
+
2238
+ // Restore and create editors
2239
+ const editorState = await restoreAndCreateEditors(state, restoredLayout);
2240
+
2241
+ // Load file icons with the updated editor state
2242
+ const {
2243
+ fileIconCache,
2244
+ updatedLayout
2245
+ } = await loadFileIcons(editorState);
2246
+
2247
+ // Merge the results
2248
+ const finalState = {
2249
+ ...editorState,
2250
+ fileIconCache,
2251
+ layout: updatedLayout
1902
2252
  };
2253
+ return finalState;
1903
2254
  }
1904
2255
  return {
1905
2256
  ...state,
@@ -2019,11 +2370,6 @@ const getMenuEntries = async (state, props) => {
2019
2370
  }
2020
2371
  };
2021
2372
 
2022
- const createViewlet = async (viewletModuleId, editorUid, tabId, bounds, uri) => {
2023
- // @ts-ignore
2024
- await invoke('Layout.createViewlet', viewletModuleId, editorUid, tabId, bounds, uri);
2025
- };
2026
-
2027
2373
  const getBasename = uri => {
2028
2374
  const lastSlashIndex = uri.lastIndexOf('/');
2029
2375
  if (lastSlashIndex === -1) {
@@ -2051,11 +2397,13 @@ const createEmptyGroup = (state, uri, requestId) => {
2051
2397
  const groupId = create();
2052
2398
  const title = getLabel(uri);
2053
2399
  const tabId = create();
2400
+ const editorUid = create();
2054
2401
  const newTab = {
2055
2402
  content: '',
2056
2403
  editorType: 'text',
2057
- editorUid: -1,
2404
+ editorUid,
2058
2405
  errorMessage: '',
2406
+ icon: '',
2059
2407
  id: tabId,
2060
2408
  isDirty: false,
2061
2409
  language: '',
@@ -2130,11 +2478,13 @@ const ensureActiveGroup = (state, uri) => {
2130
2478
  // Create a new tab with the URI in the active group
2131
2479
  const title = getLabel(uri);
2132
2480
  const tabId = create();
2481
+ const editorUid = create();
2133
2482
  const newTab = {
2134
2483
  content: '',
2135
2484
  editorType: 'text',
2136
- editorUid: -1,
2485
+ editorUid,
2137
2486
  errorMessage: '',
2487
+ icon: '',
2138
2488
  id: tabId,
2139
2489
  isDirty: false,
2140
2490
  language: '',
@@ -2149,25 +2499,6 @@ const ensureActiveGroup = (state, uri) => {
2149
2499
  return newState;
2150
2500
  };
2151
2501
 
2152
- const findTabById = (state, tabId) => {
2153
- const {
2154
- layout
2155
- } = state;
2156
- const {
2157
- groups
2158
- } = layout;
2159
- for (const group of groups) {
2160
- const tab = group.tabs.find(t => t.id === tabId);
2161
- if (tab) {
2162
- return {
2163
- groupId: group.id,
2164
- tab
2165
- };
2166
- }
2167
- }
2168
- return undefined;
2169
- };
2170
-
2171
2502
  const findTabByUri = (state, uri) => {
2172
2503
  const {
2173
2504
  layout
@@ -2233,18 +2564,6 @@ const getOptionUriOptions = options => {
2233
2564
  return uri;
2234
2565
  };
2235
2566
 
2236
- const getViewletModuleId = async uri => {
2237
- // Query RendererWorker for viewlet module ID (optional, may fail in tests)
2238
- let viewletModuleId;
2239
- try {
2240
- // @ts-ignore
2241
- viewletModuleId = await invoke('Layout.getModuleId', uri);
2242
- } catch {
2243
- // Viewlet creation is optional - silently ignore if RendererWorker isn't available
2244
- }
2245
- return viewletModuleId;
2246
- };
2247
-
2248
2567
  const switchTab = (state, groupId, tabId) => {
2249
2568
  const {
2250
2569
  layout
@@ -2314,7 +2633,7 @@ const openUri = async (state, options) => {
2314
2633
  newState: switchedState
2315
2634
  } = switchViewlet(intermediateState1);
2316
2635
  intermediateState1 = switchedState;
2317
- set$3(uid, state, intermediateState1);
2636
+ set$4(uid, state, intermediateState1);
2318
2637
 
2319
2638
  // @ts-ignore
2320
2639
 
@@ -2339,6 +2658,36 @@ const openUri = async (state, options) => {
2339
2658
 
2340
2659
  // Attachment is handled automatically by virtual DOM reference nodes
2341
2660
  const readyState = handleViewletReady(latestState, editorUid);
2661
+
2662
+ // Request file icon for the newly opened tab
2663
+ try {
2664
+ const newTab = findTabById(readyState, tabId);
2665
+ if (newTab && newTab.tab.uri) {
2666
+ const {
2667
+ newFileIconCache
2668
+ } = await getFileIconsForTabs([newTab.tab], readyState.fileIconCache);
2669
+ const icon = newFileIconCache[newTab.tab.uri] || '';
2670
+
2671
+ // Update the tab with the icon
2672
+ const stateWithIcon = {
2673
+ ...readyState,
2674
+ fileIconCache: newFileIconCache,
2675
+ layout: {
2676
+ ...readyState.layout,
2677
+ groups: readyState.layout.groups.map(group => ({
2678
+ ...group,
2679
+ tabs: group.tabs.map(tab => tab.id === tabId ? {
2680
+ ...tab,
2681
+ icon
2682
+ } : tab)
2683
+ }))
2684
+ }
2685
+ };
2686
+ return stateWithIcon;
2687
+ }
2688
+ } catch {
2689
+ // If icon request fails, continue without icon
2690
+ }
2342
2691
  return readyState;
2343
2692
  };
2344
2693
 
@@ -2348,6 +2697,13 @@ const refresh = state => {
2348
2697
  };
2349
2698
  };
2350
2699
 
2700
+ const Button = 1;
2701
+ const Div = 4;
2702
+ const Span = 8;
2703
+ const Text = 12;
2704
+ const Img = 17;
2705
+ const Pre = 51;
2706
+
2351
2707
  const text = data => {
2352
2708
  return {
2353
2709
  childCount: 0,
@@ -2359,17 +2715,18 @@ const text = data => {
2359
2715
  const CSS_CLASSES = {
2360
2716
  EDITOR_GROUPS_CONTAINER: 'editor-groups-container'};
2361
2717
 
2362
- const renderLoading = () => {
2718
+ const renderContent = content => {
2363
2719
  return [{
2364
2720
  childCount: 1,
2365
- className: 'TextEditor TextEditor--loading',
2721
+ className: 'TextEditor',
2366
2722
  type: Div
2367
2723
  }, {
2368
2724
  childCount: 1,
2369
- className: 'EditorContent EditorContent--loading',
2370
- type: Div
2371
- }, text('Loading...')];
2725
+ className: 'EditorContent',
2726
+ type: Pre
2727
+ }, text(content)];
2372
2728
  };
2729
+
2373
2730
  const renderError = errorMessage => {
2374
2731
  return [{
2375
2732
  childCount: 1,
@@ -2381,17 +2738,19 @@ const renderError = errorMessage => {
2381
2738
  type: Div
2382
2739
  }, text(`Error: ${errorMessage}`)];
2383
2740
  };
2384
- const renderContent = content => {
2741
+
2742
+ const renderLoading = () => {
2385
2743
  return [{
2386
2744
  childCount: 1,
2387
- className: 'TextEditor',
2745
+ className: 'TextEditor TextEditor--loading',
2388
2746
  type: Div
2389
2747
  }, {
2390
2748
  childCount: 1,
2391
- className: 'EditorContent',
2392
- type: Pre
2393
- }, text(content)];
2749
+ className: 'EditorContent EditorContent--loading',
2750
+ type: Div
2751
+ }, text('Loading...')];
2394
2752
  };
2753
+
2395
2754
  const renderViewletReference = tab => {
2396
2755
  return [{
2397
2756
  childCount: 0,
@@ -2400,6 +2759,7 @@ const renderViewletReference = tab => {
2400
2759
  uid: tab.editorUid
2401
2760
  }];
2402
2761
  };
2762
+
2403
2763
  const renderEditor = tab => {
2404
2764
  if (!tab) {
2405
2765
  // Keep backward compatible behavior: render empty content
@@ -2446,7 +2806,7 @@ const renderTab = (tab, isActive, tabIndex, groupIndex) => {
2446
2806
  }, {
2447
2807
  childCount: 0,
2448
2808
  className: 'TabIcon',
2449
- src: 'icons/refresh.svg',
2809
+ src: tab.icon,
2450
2810
  type: Img
2451
2811
  }, {
2452
2812
  childCount: 1,
@@ -2458,7 +2818,7 @@ const renderTab = (tab, isActive, tabIndex, groupIndex) => {
2458
2818
  'data-groupIndex': groupIndex,
2459
2819
  'data-index': tabIndex,
2460
2820
  onClick: HandleClickClose,
2461
- type: Button$1
2821
+ type: Button
2462
2822
  }, text('×')];
2463
2823
  };
2464
2824
 
@@ -2530,7 +2890,7 @@ const render2 = (uid, diffResult) => {
2530
2890
  newState,
2531
2891
  oldState
2532
2892
  } = get$2(uid);
2533
- set$3(uid, newState, newState);
2893
+ set$4(uid, newState, newState);
2534
2894
  const commands = applyRender(oldState, newState, diffResult);
2535
2895
  return commands;
2536
2896
  };
@@ -2547,7 +2907,7 @@ const renderEventListeners = () => {
2547
2907
  params: ['handleClickTab', 'event.target.dataset.groupIndex', 'event.target.dataset.index']
2548
2908
  }, {
2549
2909
  name: HandleTabContextMenu,
2550
- params: ['handleTabContextMenu', Button, ClientX, ClientY],
2910
+ params: ['handleTabContextMenu', Button$1, ClientX, ClientY],
2551
2911
  preventDefault: true
2552
2912
  }];
2553
2913
  };
@@ -2586,11 +2946,31 @@ const commandMap = {
2586
2946
  'MainArea.render2': render2,
2587
2947
  'MainArea.renderEventListeners': renderEventListeners,
2588
2948
  'MainArea.resize': wrapCommand(resize),
2589
- 'MainArea.saveState': saveState,
2949
+ 'MainArea.saveState': wrapGetter(saveState),
2590
2950
  'MainArea.selectTab': wrapCommand(selectTab),
2591
2951
  'MainArea.terminate': terminate
2592
2952
  };
2593
2953
 
2954
+ const send = port => {
2955
+ return sendMessagePortToIconThemeWorker(port, 0);
2956
+ };
2957
+ const createIconThemeWorkerRpc = async () => {
2958
+ try {
2959
+ const rpc = await LazyTransferMessagePortRpcParent.create({
2960
+ commandMap: {},
2961
+ send
2962
+ });
2963
+ return rpc;
2964
+ } catch (error) {
2965
+ throw new VError(error, `Failed to create icon theme worker rpc`);
2966
+ }
2967
+ };
2968
+
2969
+ const initializeIconThemeWorker = async () => {
2970
+ const rpc = await createIconThemeWorkerRpc();
2971
+ set$1(rpc);
2972
+ };
2973
+
2594
2974
  const initializeRendererWorker = async () => {
2595
2975
  const rpc = await WebWorkerRpcClient.create({
2596
2976
  commandMap: commandMap
@@ -2600,7 +2980,7 @@ const initializeRendererWorker = async () => {
2600
2980
 
2601
2981
  const listen = async () => {
2602
2982
  registerCommands(commandMap);
2603
- await initializeRendererWorker();
2983
+ await Promise.all([initializeRendererWorker(), initializeIconThemeWorker()]);
2604
2984
  };
2605
2985
 
2606
2986
  const main$2 = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-area-worker",
3
- "version": "3.1.0",
3
+ "version": "5.0.0",
4
4
  "description": "Main Area Worker",
5
5
  "repository": {
6
6
  "type": "git",