@lvce-editor/main-area-worker 4.0.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,12 +1941,7 @@ const createExtensionHostRpc = async () => {
1829
1941
 
1830
1942
  const initialize = async () => {
1831
1943
  const rpc = await createExtensionHostRpc();
1832
- set$1(rpc);
1833
- };
1834
-
1835
- const createViewlet = async (viewletModuleId, editorUid, tabId, bounds, uri) => {
1836
- // @ts-ignore
1837
- await invoke('Layout.createViewlet', viewletModuleId, editorUid, tabId, bounds, uri);
1944
+ set$2(rpc);
1838
1945
  };
1839
1946
 
1840
1947
  const getMaxIdFromLayout = layout => {
@@ -1852,18 +1959,6 @@ const getMaxIdFromLayout = layout => {
1852
1959
  return maxId;
1853
1960
  };
1854
1961
 
1855
- const getViewletModuleId = async uri => {
1856
- // Query RendererWorker for viewlet module ID (optional, may fail in tests)
1857
- let viewletModuleId;
1858
- try {
1859
- // @ts-ignore
1860
- viewletModuleId = await invoke('Layout.getModuleId', uri);
1861
- } catch {
1862
- // Viewlet creation is optional - silently ignore if RendererWorker isn't available
1863
- }
1864
- return viewletModuleId;
1865
- };
1866
-
1867
1962
  const isValidTab = tab => {
1868
1963
  return tab && typeof tab.id === 'number' && typeof tab.title === 'string' && typeof tab.content === 'string' && typeof tab.isDirty === 'boolean' && (tab.editorType === 'text' || tab.editorType === 'custom') && (tab.editorType !== 'custom' || typeof tab.customEditorId === 'string');
1869
1964
  };
@@ -1908,71 +2003,254 @@ const tryRestoreLayout = savedState => {
1908
2003
  return layout;
1909
2004
  };
1910
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
+
1911
2232
  const loadContent = async (state, savedState) => {
1912
2233
  const restoredLayout = tryRestoreLayout(savedState);
1913
2234
  if (restoredLayout) {
1914
2235
  const maxId = getMaxIdFromLayout(restoredLayout);
1915
2236
  setMinId(maxId);
1916
- let newState = {
1917
- ...state,
1918
- layout: restoredLayout
1919
- };
1920
-
1921
- // Create viewlets only for active tabs in each group
1922
- const TAB_HEIGHT = 35;
1923
- const bounds = {
1924
- height: newState.height - TAB_HEIGHT,
1925
- width: newState.width,
1926
- x: newState.x,
1927
- y: newState.y + TAB_HEIGHT
1928
- };
1929
- for (const group of restoredLayout.groups) {
1930
- // Find the active tab in this group
1931
- const activeTab = group.tabs.find(tab => tab.id === group.activeTabId);
1932
- if (activeTab && activeTab.uri) {
1933
- const viewletModuleId = await getViewletModuleId(activeTab.uri);
1934
- if (viewletModuleId) {
1935
- // Ensure the tab has an editorUid
1936
- const editorUid = activeTab.editorUid === -1 ? create() : activeTab.editorUid;
1937
-
1938
- // Create viewlet for the tab
1939
- newState = createViewletForTab(newState, activeTab.id);
1940
-
1941
- // Update the tab with the editorUid in the state
1942
- const updatedGroups = newState.layout.groups.map(g => {
1943
- if (g.id !== group.id) {
1944
- return g;
1945
- }
1946
- return {
1947
- ...g,
1948
- tabs: g.tabs.map(t => {
1949
- if (t.id !== activeTab.id) {
1950
- return t;
1951
- }
1952
- return {
1953
- ...t,
1954
- editorUid
1955
- };
1956
- })
1957
- };
1958
- });
1959
- newState = {
1960
- ...newState,
1961
- layout: {
1962
- ...newState.layout,
1963
- groups: updatedGroups
1964
- }
1965
- };
1966
2237
 
1967
- // Create the actual viewlet instance
1968
- await createViewlet(viewletModuleId, editorUid, activeTab.id, bounds, activeTab.uri);
2238
+ // Restore and create editors
2239
+ const editorState = await restoreAndCreateEditors(state, restoredLayout);
1969
2240
 
1970
- // Mark the viewlet as ready
1971
- newState = handleViewletReady(newState, editorUid);
1972
- }
1973
- }
1974
- }
1975
- return newState;
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
2252
+ };
2253
+ return finalState;
1976
2254
  }
1977
2255
  return {
1978
2256
  ...state,
@@ -2125,6 +2403,7 @@ const createEmptyGroup = (state, uri, requestId) => {
2125
2403
  editorType: 'text',
2126
2404
  editorUid,
2127
2405
  errorMessage: '',
2406
+ icon: '',
2128
2407
  id: tabId,
2129
2408
  isDirty: false,
2130
2409
  language: '',
@@ -2205,6 +2484,7 @@ const ensureActiveGroup = (state, uri) => {
2205
2484
  editorType: 'text',
2206
2485
  editorUid,
2207
2486
  errorMessage: '',
2487
+ icon: '',
2208
2488
  id: tabId,
2209
2489
  isDirty: false,
2210
2490
  language: '',
@@ -2219,25 +2499,6 @@ const ensureActiveGroup = (state, uri) => {
2219
2499
  return newState;
2220
2500
  };
2221
2501
 
2222
- const findTabById = (state, tabId) => {
2223
- const {
2224
- layout
2225
- } = state;
2226
- const {
2227
- groups
2228
- } = layout;
2229
- for (const group of groups) {
2230
- const tab = group.tabs.find(t => t.id === tabId);
2231
- if (tab) {
2232
- return {
2233
- groupId: group.id,
2234
- tab
2235
- };
2236
- }
2237
- }
2238
- return undefined;
2239
- };
2240
-
2241
2502
  const findTabByUri = (state, uri) => {
2242
2503
  const {
2243
2504
  layout
@@ -2372,7 +2633,7 @@ const openUri = async (state, options) => {
2372
2633
  newState: switchedState
2373
2634
  } = switchViewlet(intermediateState1);
2374
2635
  intermediateState1 = switchedState;
2375
- set$3(uid, state, intermediateState1);
2636
+ set$4(uid, state, intermediateState1);
2376
2637
 
2377
2638
  // @ts-ignore
2378
2639
 
@@ -2397,6 +2658,36 @@ const openUri = async (state, options) => {
2397
2658
 
2398
2659
  // Attachment is handled automatically by virtual DOM reference nodes
2399
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
+ }
2400
2691
  return readyState;
2401
2692
  };
2402
2693
 
@@ -2406,6 +2697,13 @@ const refresh = state => {
2406
2697
  };
2407
2698
  };
2408
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
+
2409
2707
  const text = data => {
2410
2708
  return {
2411
2709
  childCount: 0,
@@ -2417,17 +2715,18 @@ const text = data => {
2417
2715
  const CSS_CLASSES = {
2418
2716
  EDITOR_GROUPS_CONTAINER: 'editor-groups-container'};
2419
2717
 
2420
- const renderLoading = () => {
2718
+ const renderContent = content => {
2421
2719
  return [{
2422
2720
  childCount: 1,
2423
- className: 'TextEditor TextEditor--loading',
2721
+ className: 'TextEditor',
2424
2722
  type: Div
2425
2723
  }, {
2426
2724
  childCount: 1,
2427
- className: 'EditorContent EditorContent--loading',
2428
- type: Div
2429
- }, text('Loading...')];
2725
+ className: 'EditorContent',
2726
+ type: Pre
2727
+ }, text(content)];
2430
2728
  };
2729
+
2431
2730
  const renderError = errorMessage => {
2432
2731
  return [{
2433
2732
  childCount: 1,
@@ -2439,17 +2738,19 @@ const renderError = errorMessage => {
2439
2738
  type: Div
2440
2739
  }, text(`Error: ${errorMessage}`)];
2441
2740
  };
2442
- const renderContent = content => {
2741
+
2742
+ const renderLoading = () => {
2443
2743
  return [{
2444
2744
  childCount: 1,
2445
- className: 'TextEditor',
2745
+ className: 'TextEditor TextEditor--loading',
2446
2746
  type: Div
2447
2747
  }, {
2448
2748
  childCount: 1,
2449
- className: 'EditorContent',
2450
- type: Pre
2451
- }, text(content)];
2749
+ className: 'EditorContent EditorContent--loading',
2750
+ type: Div
2751
+ }, text('Loading...')];
2452
2752
  };
2753
+
2453
2754
  const renderViewletReference = tab => {
2454
2755
  return [{
2455
2756
  childCount: 0,
@@ -2458,6 +2759,7 @@ const renderViewletReference = tab => {
2458
2759
  uid: tab.editorUid
2459
2760
  }];
2460
2761
  };
2762
+
2461
2763
  const renderEditor = tab => {
2462
2764
  if (!tab) {
2463
2765
  // Keep backward compatible behavior: render empty content
@@ -2504,7 +2806,7 @@ const renderTab = (tab, isActive, tabIndex, groupIndex) => {
2504
2806
  }, {
2505
2807
  childCount: 0,
2506
2808
  className: 'TabIcon',
2507
- src: 'icons/refresh.svg',
2809
+ src: tab.icon,
2508
2810
  type: Img
2509
2811
  }, {
2510
2812
  childCount: 1,
@@ -2516,7 +2818,7 @@ const renderTab = (tab, isActive, tabIndex, groupIndex) => {
2516
2818
  'data-groupIndex': groupIndex,
2517
2819
  'data-index': tabIndex,
2518
2820
  onClick: HandleClickClose,
2519
- type: Button$1
2821
+ type: Button
2520
2822
  }, text('×')];
2521
2823
  };
2522
2824
 
@@ -2588,7 +2890,7 @@ const render2 = (uid, diffResult) => {
2588
2890
  newState,
2589
2891
  oldState
2590
2892
  } = get$2(uid);
2591
- set$3(uid, newState, newState);
2893
+ set$4(uid, newState, newState);
2592
2894
  const commands = applyRender(oldState, newState, diffResult);
2593
2895
  return commands;
2594
2896
  };
@@ -2605,7 +2907,7 @@ const renderEventListeners = () => {
2605
2907
  params: ['handleClickTab', 'event.target.dataset.groupIndex', 'event.target.dataset.index']
2606
2908
  }, {
2607
2909
  name: HandleTabContextMenu,
2608
- params: ['handleTabContextMenu', Button, ClientX, ClientY],
2910
+ params: ['handleTabContextMenu', Button$1, ClientX, ClientY],
2609
2911
  preventDefault: true
2610
2912
  }];
2611
2913
  };
@@ -2649,6 +2951,26 @@ const commandMap = {
2649
2951
  'MainArea.terminate': terminate
2650
2952
  };
2651
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
+
2652
2974
  const initializeRendererWorker = async () => {
2653
2975
  const rpc = await WebWorkerRpcClient.create({
2654
2976
  commandMap: commandMap
@@ -2658,7 +2980,7 @@ const initializeRendererWorker = async () => {
2658
2980
 
2659
2981
  const listen = async () => {
2660
2982
  registerCommands(commandMap);
2661
- await initializeRendererWorker();
2983
+ await Promise.all([initializeRendererWorker(), initializeIconThemeWorker()]);
2662
2984
  };
2663
2985
 
2664
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": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Main Area Worker",
5
5
  "repository": {
6
6
  "type": "git",