@lvce-editor/main-area-worker 9.56.2 → 9.58.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.
@@ -488,7 +488,7 @@ const execute = (command, ...args) => {
488
488
 
489
489
  const Two$1 = '2.0';
490
490
  const callbacks = Object.create(null);
491
- const get$2 = id => {
491
+ const get$3 = id => {
492
492
  return callbacks[id];
493
493
  };
494
494
  const remove$1 = id => {
@@ -678,7 +678,7 @@ const warn = (...args) => {
678
678
  console.warn(...args);
679
679
  };
680
680
  const resolve = (id, response) => {
681
- const fn = get$2(id);
681
+ const fn = get$3(id);
682
682
  if (!fn) {
683
683
  console.log(response);
684
684
  warn(`callback ${id} may already be disposed`);
@@ -1335,7 +1335,7 @@ const rpcs = Object.create(null);
1335
1335
  const set$8 = (id, rpc) => {
1336
1336
  rpcs[id] = rpc;
1337
1337
  };
1338
- const get$1 = id => {
1338
+ const get$2 = id => {
1339
1339
  return rpcs[id];
1340
1340
  };
1341
1341
  const remove = id => {
@@ -1346,18 +1346,18 @@ const remove = id => {
1346
1346
  const create$3 = rpcId => {
1347
1347
  return {
1348
1348
  async dispose() {
1349
- const rpc = get$1(rpcId);
1349
+ const rpc = get$2(rpcId);
1350
1350
  await rpc.dispose();
1351
1351
  },
1352
1352
  // @ts-ignore
1353
1353
  invoke(method, ...params) {
1354
- const rpc = get$1(rpcId);
1354
+ const rpc = get$2(rpcId);
1355
1355
  // @ts-ignore
1356
1356
  return rpc.invoke(method, ...params);
1357
1357
  },
1358
1358
  // @ts-ignore
1359
1359
  invokeAndTransfer(method, ...params) {
1360
- const rpc = get$1(rpcId);
1360
+ const rpc = get$2(rpcId);
1361
1361
  // @ts-ignore
1362
1362
  return rpc.invokeAndTransfer(method, ...params);
1363
1363
  },
@@ -1499,18 +1499,102 @@ const confirm$1 = async (message, options) => {
1499
1499
  const result = await invoke$1('ConfirmPrompt.prompt', message, options);
1500
1500
  return result;
1501
1501
  };
1502
+ const getPreference = async key => {
1503
+ return await invoke$1('Preferences.get', key);
1504
+ };
1505
+
1506
+ const maxClosedTabs = 20;
1507
+ const pendingOperations = new Map();
1508
+ const sessionId = encodeURIComponent(`session-${new Date().toISOString()}`);
1509
+ const getKey = uid => {
1510
+ return `https://lvce-editor.invalid/closed-tabs/${sessionId}/${uid}`;
1511
+ };
1512
+ const run = async (uid, operation) => {
1513
+ const previous = pendingOperations.get(uid)?.promise || Promise.resolve();
1514
+ const id = {};
1515
+ const current = (async () => {
1516
+ await previous;
1517
+ try {
1518
+ return await operation();
1519
+ } finally {
1520
+ if (pendingOperations.get(uid)?.id === id) {
1521
+ pendingOperations.delete(uid);
1522
+ }
1523
+ }
1524
+ })();
1525
+ pendingOperations.set(uid, {
1526
+ id,
1527
+ promise: current
1528
+ });
1529
+ return await current;
1530
+ };
1531
+ const isClosedTabEntry = value => {
1532
+ if (!value || typeof value !== 'object') {
1533
+ return false;
1534
+ }
1535
+ const entry = value;
1536
+ return Boolean(entry.group && typeof entry.group === 'object' && entry.tab && typeof entry.tab === 'object' && typeof entry.groupIndex === 'number' && typeof entry.tabIndex === 'number');
1537
+ };
1538
+ const getEntries = async key => {
1539
+ const entries = await invoke$1('CacheStorage.getJson', key);
1540
+ return Array.isArray(entries) ? entries.filter(isClosedTabEntry) : [];
1541
+ };
1542
+ const compact = entry => {
1543
+ return {
1544
+ ...entry,
1545
+ group: {
1546
+ ...entry.group,
1547
+ tabs: []
1548
+ }
1549
+ };
1550
+ };
1551
+ const add = (uid, entries) => {
1552
+ if (entries.length === 0) {
1553
+ return Promise.resolve();
1554
+ }
1555
+ return run(uid, async () => {
1556
+ try {
1557
+ const key = getKey(uid);
1558
+ const existing = await getEntries(key);
1559
+ const compactEntries = entries.map(compact);
1560
+ await invoke$1('CacheStorage.setJson', key, [...existing, ...compactEntries].slice(-maxClosedTabs));
1561
+ } catch {
1562
+ // Closed tab history is optional and must never break editor commands.
1563
+ }
1564
+ });
1565
+ };
1566
+ const clear = uid => {
1567
+ return run(uid, async () => {
1568
+ try {
1569
+ await invoke$1('CacheStorage.setJson', getKey(uid), []);
1570
+ } catch {
1571
+ // Closed tab history is optional and must never break workspace changes.
1572
+ }
1573
+ });
1574
+ };
1575
+ const takeLast = uid => {
1576
+ return run(uid, async () => {
1577
+ try {
1578
+ const key = getKey(uid);
1579
+ const entries = await getEntries(key);
1580
+ const entry = entries.at(-1);
1581
+ if (!isClosedTabEntry(entry)) {
1582
+ return undefined;
1583
+ }
1584
+ await invoke$1('CacheStorage.setJson', key, entries.slice(0, -1));
1585
+ return entry;
1586
+ } catch {
1587
+ return undefined;
1588
+ }
1589
+ });
1590
+ };
1502
1591
 
1503
1592
  const addClosedTabs = (state, entries) => {
1504
- const {
1505
- closedTabs
1506
- } = state;
1507
1593
  if (entries.length === 0) {
1508
1594
  return state;
1509
1595
  }
1510
- return {
1511
- ...state,
1512
- closedTabs: [...closedTabs, ...entries].slice(-20)
1513
- };
1596
+ void add(state.uid, entries);
1597
+ return state;
1514
1598
  };
1515
1599
 
1516
1600
  const getGroupIndexById = (state, groupId) => {
@@ -1735,7 +1819,7 @@ const withActiveEditorChangeAsync = fn => {
1735
1819
 
1736
1820
  const registry = create$4();
1737
1821
  const {
1738
- get,
1822
+ get: get$1,
1739
1823
  getCommandIds,
1740
1824
  getKeys: getKeys$1,
1741
1825
  registerCommands,
@@ -1984,7 +2068,7 @@ const handleCreate = async command => {
1984
2068
  const {
1985
2069
  newState: state,
1986
2070
  oldState
1987
- } = get(command.uid);
2071
+ } = get$1(command.uid);
1988
2072
  const readyState = handleViewletReady(state, command.editorUid, title);
1989
2073
  set$1(command.uid, oldState, readyState);
1990
2074
  return readyState;
@@ -2527,7 +2611,6 @@ const normalizeLayoutDirection = direction => {
2527
2611
  const create$1 = (uid, uri, x, y, width, height, platform, assetDir, tabHeight = 35) => {
2528
2612
  const state = {
2529
2613
  assetDir,
2530
- closedTabs: [],
2531
2614
  fileIconCache: {},
2532
2615
  height,
2533
2616
  homeDirUri: '',
@@ -2538,8 +2621,8 @@ const create$1 = (uid, uri, x, y, width, height, platform, assetDir, tabHeight =
2538
2621
  direction: Horizontal,
2539
2622
  groups: []
2540
2623
  },
2541
- maxOpenEditorGroups: Infinity,
2542
- maxOpenEditors: Infinity,
2624
+ maxOpenEditorGroups: -1,
2625
+ maxOpenEditors: -1,
2543
2626
  minGroupHeightPx: 80,
2544
2627
  minGroupWidthPx: 250,
2545
2628
  platform,
@@ -2600,7 +2683,7 @@ const diff2 = uid => {
2600
2683
  const {
2601
2684
  newState,
2602
2685
  oldState
2603
- } = get(uid);
2686
+ } = get$1(uid);
2604
2687
  const result = diff(oldState, newState);
2605
2688
  return result;
2606
2689
  };
@@ -3123,7 +3206,7 @@ const startContentLoading = async (oldState, state, tabId, path, requestId) => {
3123
3206
  } = state;
3124
3207
  try {
3125
3208
  const getLatestState = () => {
3126
- return get(uid).newState;
3209
+ return get$1(uid).newState;
3127
3210
  };
3128
3211
  set$1(uid, oldState, state);
3129
3212
  const newState = await loadTabContentAsync(tabId, path, requestId, getLatestState);
@@ -3303,7 +3386,7 @@ const getActiveEditorUid = state => {
3303
3386
  };
3304
3387
 
3305
3388
  const getComponentState = uid => {
3306
- return get(uid).newState;
3389
+ return get$1(uid).newState;
3307
3390
  };
3308
3391
 
3309
3392
  const getMenuIds = () => {
@@ -3334,6 +3417,8 @@ const handleClickTogglePreview = async state => {
3334
3417
  };
3335
3418
 
3336
3419
  const CloseGroup = 'close-group';
3420
+ const ConfigureLargeFileLimit = 'configure-large-file-limit';
3421
+ const OpenLargeFile = 'open-large-file';
3337
3422
  const OpenInTextEditor$1 = 'open-in-text-editor';
3338
3423
  const RetryOpen = 'retry-open';
3339
3424
  const RestoreClosedTab = 'restore-closed-tab';
@@ -3406,7 +3491,7 @@ const getCurrentState = state => {
3406
3491
  const {
3407
3492
  uid
3408
3493
  } = state;
3409
- const stateFromStore = get(uid);
3494
+ const stateFromStore = get$1(uid);
3410
3495
  if (!stateFromStore) {
3411
3496
  set$1(uid, state, state);
3412
3497
  return state;
@@ -3526,6 +3611,36 @@ const getEditorInputTitle = editorInput => {
3526
3611
  }
3527
3612
  };
3528
3613
 
3614
+ const get = async key => {
3615
+ return getPreference(key);
3616
+ };
3617
+
3618
+ const defaultMaxFileSizeMb = 50;
3619
+ const bytesPerMegabyte = 1024 * 1024;
3620
+ const getMaxFileSize = async () => {
3621
+ try {
3622
+ const configuredLimit = await get('files.maxFileSizeMB');
3623
+ if (typeof configuredLimit === 'number' && Number.isFinite(configuredLimit) && configuredLimit > 0) {
3624
+ return configuredLimit * bytesPerMegabyte;
3625
+ }
3626
+ } catch {
3627
+ // Older renderer workers do not expose this preference yet.
3628
+ }
3629
+ return defaultMaxFileSizeMb * bytesPerMegabyte;
3630
+ };
3631
+ const getLargeFileSize = async (editorInput, forceOpen = false) => {
3632
+ if (editorInput.type !== 'editor' || forceOpen || !editorInput.uri.startsWith('file://')) {
3633
+ return undefined;
3634
+ }
3635
+ try {
3636
+ const [fileSize, maxFileSize] = await Promise.all([invoke$1('FileSystem.getFileSize', editorInput.uri), getMaxFileSize()]);
3637
+ return typeof fileSize === 'number' && fileSize > maxFileSize ? fileSize : undefined;
3638
+ } catch {
3639
+ // File systems without stat support should retain the existing open behavior.
3640
+ return undefined;
3641
+ }
3642
+ };
3643
+
3529
3644
  const getUriTitle = (uri, homeDirUri) => {
3530
3645
  if (!uri) {
3531
3646
  return undefined;
@@ -3741,6 +3856,7 @@ const getStateWithTab = (currentState, editorInput, existingTab, shouldRetryExis
3741
3856
  editorInput,
3742
3857
  editorType,
3743
3858
  errorMessage: '',
3859
+ fileSize: undefined,
3744
3860
  loadingState: 'loading',
3745
3861
  title,
3746
3862
  uri,
@@ -3966,11 +4082,11 @@ const getActivePreviewEditorUid = state => {
3966
4082
  const activeTab = activeGroup?.tabs.find(tab => tab.id === activeGroup.activeTabId);
3967
4083
  return activeTab?.isPreview ? activeTab.editorUid : -1;
3968
4084
  };
3969
- const shouldRetryExistingTab = (existingTab, editorInput) => {
4085
+ const shouldRetryExistingTab = (existingTab, editorInput, forceOpen) => {
3970
4086
  if (!existingTab) {
3971
4087
  return false;
3972
4088
  }
3973
- return existingTab.tab.loadingState === 'error' || editorInput.type === 'editor' && editorInput.forceText === true && existingTab.tab.editorInput?.type === 'binary';
4089
+ return existingTab.tab.loadingState === 'error' || forceOpen && existingTab.tab.loadingState === 'large' || editorInput.type === 'editor' && editorInput.forceText === true && existingTab.tab.editorInput?.type === 'binary';
3974
4090
  };
3975
4091
  const openInputWithContext = async (context, options) => {
3976
4092
  const state = context.getState();
@@ -3985,7 +4101,7 @@ const openInputWithContext = async (context, options) => {
3985
4101
  const editorType = getEditorInputEditorType(editorInput);
3986
4102
  const currentState = state;
3987
4103
  const existingTab = options.reuseExisting === false ? undefined : findTabByUri(currentState, uri);
3988
- const shouldRetry = shouldRetryExistingTab(existingTab, editorInput);
4104
+ const shouldRetry = shouldRetryExistingTab(existingTab, editorInput, options.forceOpen === true);
3989
4105
  if (existingTab && !shouldRetry) {
3990
4106
  const switchedState = getExistingTabState(currentState, existingTab, preview);
3991
4107
  await context.updateState(() => switchedState);
@@ -4020,6 +4136,17 @@ const openInputWithContext = async (context, options) => {
4020
4136
  await context.updateState(() => binaryState);
4021
4137
  return;
4022
4138
  }
4139
+ const fileSize = await getLargeFileSize(editorInput, options.forceOpen === true);
4140
+ if (fileSize !== undefined) {
4141
+ const latestState = context.getState();
4142
+ const largeFileState = updateTab(latestState, tabId, {
4143
+ editorUid: -1,
4144
+ fileSize,
4145
+ loadingState: 'large'
4146
+ });
4147
+ await context.updateState(() => largeFileState);
4148
+ return;
4149
+ }
4023
4150
  try {
4024
4151
  const viewletModuleId = await getViewletModuleIdForEditorInput(editorInput);
4025
4152
  const stateAfterModuleId = context.getState();
@@ -4081,9 +4208,9 @@ const openInput = async (state, options) => {
4081
4208
  } = state;
4082
4209
  let currentState = getCurrentState(state);
4083
4210
  const context = {
4084
- getState: () => get(uid)?.newState ?? currentState,
4211
+ getState: () => get$1(uid)?.newState ?? currentState,
4085
4212
  updateState: updater => {
4086
- const storedState = get(uid);
4213
+ const storedState = get$1(uid);
4087
4214
  const latestState = storedState?.newState ?? currentState;
4088
4215
  currentState = updater(latestState);
4089
4216
  set$1(uid, storedState?.oldState ?? state, currentState);
@@ -4114,6 +4241,56 @@ const openBinaryAsText = async state => {
4114
4241
  });
4115
4242
  };
4116
4243
 
4244
+ const openLargeFile = async state => {
4245
+ const activeTabData = getActiveTab(state);
4246
+ const editorInput = activeTabData?.tab.editorInput;
4247
+ if (!activeTabData || editorInput?.type !== 'editor') {
4248
+ return state;
4249
+ }
4250
+ return openInput(state, {
4251
+ editorInput,
4252
+ focus: false,
4253
+ forceOpen: true,
4254
+ preview: activeTabData.tab.isPreview
4255
+ });
4256
+ };
4257
+
4258
+ const getOptionUriOptions = options => {
4259
+ if (typeof options === 'string') {
4260
+ return options;
4261
+ }
4262
+ return options.uri;
4263
+ };
4264
+
4265
+ const getViewletContext = (options, viewletContext) => {
4266
+ if (viewletContext !== undefined || typeof options === 'string') {
4267
+ return viewletContext;
4268
+ }
4269
+ const context = Object.fromEntries(Object.entries(options).filter(([key]) => key !== 'focus' && key !== 'preview' && key !== 'reuseExisting' && key !== 'uri'));
4270
+ return Object.keys(context).length === 0 ? undefined : context;
4271
+ };
4272
+ const getOpenInputOptions = (options, focus = true, viewletContext) => {
4273
+ const uri = getOptionUriOptions(options);
4274
+ const preview = typeof options === 'string' ? false : options.preview ?? false;
4275
+ const reuseExisting = typeof options === 'string' ? true : options.reuseExisting ?? true;
4276
+ const context = getViewletContext(options, viewletContext);
4277
+ return {
4278
+ ...(context !== undefined && {
4279
+ args: [context]
4280
+ }),
4281
+ editorInput: getNormalizedOpenEditorInput(uri),
4282
+ focus: typeof options === 'string' ? focus : options.focus,
4283
+ preview,
4284
+ reuseExisting
4285
+ };
4286
+ };
4287
+ const openUri = async (state, options, focus = true, viewletContext) => {
4288
+ return openInput(state, getOpenInputOptions(options, focus, viewletContext));
4289
+ };
4290
+ const openUriWithContext = async (context, options, focus = true, viewletContext) => {
4291
+ await openInputWithContext(context, getOpenInputOptions(options, focus, viewletContext));
4292
+ };
4293
+
4117
4294
  const parseRawGroupId = rawGroupId => {
4118
4295
  if (!rawGroupId) {
4119
4296
  return undefined;
@@ -4148,15 +4325,6 @@ const getRestoredTab = tab => {
4148
4325
  loadingState: undefined
4149
4326
  });
4150
4327
  };
4151
- const getStateWithoutLastClosedTab = state => {
4152
- const {
4153
- closedTabs
4154
- } = state;
4155
- return {
4156
- ...state,
4157
- closedTabs: closedTabs.slice(0, -1)
4158
- };
4159
- };
4160
4328
  const restoreExistingUri = (state, entry) => {
4161
4329
  const {
4162
4330
  layout
@@ -4179,14 +4347,13 @@ const restoreExistingUri = (state, entry) => {
4179
4347
  if (tabIndex === -1) {
4180
4348
  return undefined;
4181
4349
  }
4182
- const newStateWithoutClosedTab = getStateWithoutLastClosedTab(state);
4183
- const groups = focusGroup(newStateWithoutClosedTab.layout.groups, existing.groupId, existing.tab.id);
4350
+ const groups = focusGroup(state.layout.groups, existing.groupId, existing.tab.id);
4184
4351
  return {
4185
4352
  groupIndex,
4186
4353
  newState: {
4187
- ...newStateWithoutClosedTab,
4354
+ ...state,
4188
4355
  layout: {
4189
- ...newStateWithoutClosedTab.layout,
4356
+ ...state.layout,
4190
4357
  activeGroupId: existing.groupId,
4191
4358
  groups
4192
4359
  }
@@ -4210,7 +4377,6 @@ const restoreIntoExistingGroup = (state, entry) => {
4210
4377
  const tabIndex = clampIndex(entry.tabIndex, 0, group.tabs.length);
4211
4378
  const tabs = [...group.tabs];
4212
4379
  tabs.splice(tabIndex, 0, restoredTab);
4213
- const newStateWithoutClosedTab = getStateWithoutLastClosedTab(state);
4214
4380
  const updatedGroups = groups.map((currentGroup, index) => {
4215
4381
  if (index === groupIndex) {
4216
4382
  return {
@@ -4229,9 +4395,9 @@ const restoreIntoExistingGroup = (state, entry) => {
4229
4395
  return {
4230
4396
  groupIndex,
4231
4397
  newState: {
4232
- ...newStateWithoutClosedTab,
4398
+ ...state,
4233
4399
  layout: {
4234
- ...newStateWithoutClosedTab.layout,
4400
+ ...state.layout,
4235
4401
  activeGroupId: group.id,
4236
4402
  groups: updatedGroups
4237
4403
  }
@@ -4249,18 +4415,17 @@ const createRestoredGroup = entry => {
4249
4415
  };
4250
4416
  };
4251
4417
  const restoreIntoRecreatedGroup = (state, entry) => {
4252
- const newStateWithoutClosedTab = getStateWithoutLastClosedTab(state);
4253
4418
  const restoredGroup = createRestoredGroup(entry);
4254
4419
  const {
4255
4420
  groups
4256
- } = newStateWithoutClosedTab.layout;
4421
+ } = state.layout;
4257
4422
  if (groups.length === 0) {
4258
4423
  return {
4259
4424
  groupIndex: 0,
4260
4425
  newState: {
4261
- ...newStateWithoutClosedTab,
4426
+ ...state,
4262
4427
  layout: {
4263
- ...newStateWithoutClosedTab.layout,
4428
+ ...state.layout,
4264
4429
  activeGroupId: restoredGroup.id,
4265
4430
  groups: [restoredGroup]
4266
4431
  }
@@ -4277,9 +4442,9 @@ const restoreIntoRecreatedGroup = (state, entry) => {
4277
4442
  return {
4278
4443
  groupIndex,
4279
4444
  newState: {
4280
- ...newStateWithoutClosedTab,
4445
+ ...state,
4281
4446
  layout: {
4282
- ...newStateWithoutClosedTab.layout,
4447
+ ...state.layout,
4283
4448
  activeGroupId: restoredGroup.id,
4284
4449
  groups: redistributeSizesWithRounding(insertedGroups)
4285
4450
  }
@@ -4287,63 +4452,21 @@ const restoreIntoRecreatedGroup = (state, entry) => {
4287
4452
  tabIndex: 0
4288
4453
  };
4289
4454
  };
4290
- const restoreClosedTabState = state => {
4291
- const {
4292
- closedTabs
4293
- } = state;
4294
- const entry = closedTabs.at(-1);
4295
- if (!entry) {
4296
- return undefined;
4297
- }
4455
+ const restoreClosedTabState = (state, entry) => {
4298
4456
  return restoreExistingUri(state, entry) || restoreIntoExistingGroup(state, entry) || restoreIntoRecreatedGroup(state, entry);
4299
4457
  };
4300
4458
 
4301
4459
  const restoreClosedTab = async state => {
4302
- const restored = restoreClosedTabState(state);
4303
- if (!restored) {
4460
+ const entry = await takeLast(state.uid);
4461
+ if (!entry) {
4304
4462
  return state;
4305
4463
  }
4464
+ const restored = restoreClosedTabState(state, entry);
4306
4465
  const newState = await selectTab(restored.newState, restored.groupIndex, restored.tabIndex);
4307
4466
  set$1(state.uid, state, newState);
4308
4467
  return newState;
4309
4468
  };
4310
4469
 
4311
- const getOptionUriOptions = options => {
4312
- if (typeof options === 'string') {
4313
- return options;
4314
- }
4315
- return options.uri;
4316
- };
4317
-
4318
- const getViewletContext = (options, viewletContext) => {
4319
- if (viewletContext !== undefined || typeof options === 'string') {
4320
- return viewletContext;
4321
- }
4322
- const context = Object.fromEntries(Object.entries(options).filter(([key]) => key !== 'focus' && key !== 'preview' && key !== 'reuseExisting' && key !== 'uri'));
4323
- return Object.keys(context).length === 0 ? undefined : context;
4324
- };
4325
- const getOpenInputOptions = (options, focus = true, viewletContext) => {
4326
- const uri = getOptionUriOptions(options);
4327
- const preview = typeof options === 'string' ? false : options.preview ?? false;
4328
- const reuseExisting = typeof options === 'string' ? true : options.reuseExisting ?? true;
4329
- const context = getViewletContext(options, viewletContext);
4330
- return {
4331
- ...(context !== undefined && {
4332
- args: [context]
4333
- }),
4334
- editorInput: getNormalizedOpenEditorInput(uri),
4335
- focus: typeof options === 'string' ? focus : options.focus,
4336
- preview,
4337
- reuseExisting
4338
- };
4339
- };
4340
- const openUri = async (state, options, focus = true, viewletContext) => {
4341
- return openInput(state, getOpenInputOptions(options, focus, viewletContext));
4342
- };
4343
- const openUriWithContext = async (context, options, focus = true, viewletContext) => {
4344
- await openInputWithContext(context, getOpenInputOptions(options, focus, viewletContext));
4345
- };
4346
-
4347
4470
  const retryOpen = async state => {
4348
4471
  const activeTabData = getActiveTab(state);
4349
4472
  if (!activeTabData) {
@@ -4563,8 +4686,12 @@ const handleClickAction = async (state, action, rawGroupId) => {
4563
4686
  }
4564
4687
  return closeEditorGroup$1(state, groupId);
4565
4688
  }
4689
+ case ConfigureLargeFileLimit:
4690
+ return openUri(state, 'settings://');
4566
4691
  case OpenInTextEditor$1:
4567
4692
  return openBinaryAsText(state);
4693
+ case OpenLargeFile:
4694
+ return openLargeFile(state);
4568
4695
  case RetryOpen:
4569
4696
  return retryOpen(state);
4570
4697
  case SplitRight$1:
@@ -5269,12 +5396,17 @@ const TextEditorError = 'TextEditor TextEditorError';
5269
5396
  const EditorContentError = 'EditorContent EditorContentError';
5270
5397
  const TextEditorBinary = 'TextEditor TextEditorError TextEditorBinary';
5271
5398
  const EditorContentBinary = 'EditorContent EditorContentError EditorContentBinary';
5399
+ const TextEditorLargeFile = 'TextEditor TextEditorError TextEditorLargeFile';
5400
+ const EditorContentLargeFile = 'EditorContent EditorContentError EditorContentLargeFile';
5401
+ const EditorContentLargeFileActions = 'EditorContentLargeFileActions';
5402
+ const EditorLargeFileWarningIcon = 'MaskIcon MaskIconWarning EditorLargeFileWarningIcon';
5272
5403
  const DragOverlay = 'DragOverlay';
5273
5404
  const Main = 'Main';
5274
5405
  const EDITOR_GROUPS_CONTAINER = 'editor-groups-container';
5275
5406
  const TabIcon = 'TabIcon';
5276
5407
  const TabTitle = 'TabTitle';
5277
5408
  const Button = 'Button';
5409
+ const ButtonPrimary = 'ButtonPrimary';
5278
5410
  const ButtonSecondary = 'ButtonSecondary';
5279
5411
  const EditorContent = 'EditorContent';
5280
5412
  const EditorTabCloseButton = 'EditorTabCloseButton';
@@ -5380,7 +5512,7 @@ const newFile = async state => {
5380
5512
  // After viewlet is created, get the latest state and mark it as ready
5381
5513
  const {
5382
5514
  newState: latestState
5383
- } = get(uid);
5515
+ } = get$1(uid);
5384
5516
  const readyState = handleViewletReady(latestState, actualEditorUid, title);
5385
5517
  return readyState;
5386
5518
  };
@@ -6047,6 +6179,13 @@ const handleUriChange = async (state, oldUri, newUri) => {
6047
6179
  layout: result.updatedLayout
6048
6180
  };
6049
6181
  };
6182
+ const handleUriChangeWithContext = async (context, oldUri, newUri) => {
6183
+ const state = context.getState();
6184
+ const newState = await handleUriChange(state, oldUri, newUri);
6185
+ if (newState !== state) {
6186
+ await context.updateState(() => newState);
6187
+ }
6188
+ };
6050
6189
 
6051
6190
  const toFileUri = path => {
6052
6191
  if (!path) {
@@ -6318,11 +6457,8 @@ const loadContent$1 = async (state, savedState) => {
6318
6457
  };
6319
6458
 
6320
6459
  const handleWorkspaceChange = async (state, _workspacePath, savedState) => {
6321
- const newState = await loadContent$1(state, savedState);
6322
- return {
6323
- ...newState,
6324
- closedTabs: []
6325
- };
6460
+ await clear(state.uid);
6461
+ return loadContent$1(state, savedState);
6326
6462
  };
6327
6463
 
6328
6464
  const getEditorInputUris = editorInput => {
@@ -6460,6 +6596,7 @@ const CloseSaved = 'Close Saved';
6460
6596
  const CloseToTheRight = 'Close To The Right';
6461
6597
  const CopyPath = 'Copy Path';
6462
6598
  const CopyRelativePath = 'Copy Relative Path';
6599
+ const ConfigureLimit = 'Configure Limit';
6463
6600
  const FindFileReferences = 'Find File References';
6464
6601
  const ReopenEditorWith = 'Reopen Editor With...';
6465
6602
  const Share = 'Share';
@@ -6474,8 +6611,10 @@ const CopyIntoNewWindow = 'Copy into New Window';
6474
6611
  const NewTextFile = 'New Text File';
6475
6612
  const NewWindow = 'New Window';
6476
6613
  const OpenFile = 'Open File';
6614
+ const OpenAnyway = 'Open Anyway';
6477
6615
  const OpenInTextEditor = 'Open in Text Editor';
6478
6616
  const BinaryFileNotDisplayed = 'The file is not displayed in the text editor because its contents are binary.';
6617
+ const LargeFileNotDisplayed = 'The file is not displayed in the text editor because it is very large';
6479
6618
  const SplitDown = 'Split Down';
6480
6619
  const SplitEditorGroup = 'Split Editor Group';
6481
6620
  const SplitLeft = 'Split Left';
@@ -6493,6 +6632,15 @@ const openInTextEditor = () => {
6493
6632
  const binaryFileNotDisplayed = () => {
6494
6633
  return i18nString(BinaryFileNotDisplayed);
6495
6634
  };
6635
+ const configureLimit = () => {
6636
+ return i18nString(ConfigureLimit);
6637
+ };
6638
+ const largeFileNotDisplayed = () => {
6639
+ return i18nString(LargeFileNotDisplayed);
6640
+ };
6641
+ const openAnyway = () => {
6642
+ return i18nString(OpenAnyway);
6643
+ };
6496
6644
  const splitUp = () => {
6497
6645
  return i18nString(SplitUp);
6498
6646
  };
@@ -7400,7 +7548,7 @@ const editorContentBinaryNode = {
7400
7548
  className: EditorContentBinary,
7401
7549
  type: Div
7402
7550
  };
7403
- const paragraphNode$1 = {
7551
+ const paragraphNode$2 = {
7404
7552
  childCount: 1,
7405
7553
  type: P
7406
7554
  };
@@ -7413,7 +7561,7 @@ const openInTextEditorButtonNode = {
7413
7561
  type: Button$2
7414
7562
  };
7415
7563
  const renderBinary = () => {
7416
- return [textEditorBinaryNode, editorContentBinaryNode, paragraphNode$1, text(binaryFileNotDisplayed()), openInTextEditorButtonNode, text(openInTextEditor())];
7564
+ return [textEditorBinaryNode, editorContentBinaryNode, paragraphNode$2, text(binaryFileNotDisplayed()), openInTextEditorButtonNode, text(openInTextEditor())];
7417
7565
  };
7418
7566
 
7419
7567
  const textEditorNode = {
@@ -7440,7 +7588,7 @@ const editorContentErrorNode = {
7440
7588
  className: EditorContentError,
7441
7589
  type: Div
7442
7590
  };
7443
- const paragraphNode = {
7591
+ const paragraphNode$1 = {
7444
7592
  childCount: 1,
7445
7593
  type: P
7446
7594
  };
@@ -7453,7 +7601,53 @@ const retryButtonNode = {
7453
7601
  type: Button$2
7454
7602
  };
7455
7603
  const renderError = errorMessage => {
7456
- return [textEditorErrorNode, editorContentErrorNode, paragraphNode, text(`Error: ${errorMessage}`), retryButtonNode, text(retry())];
7604
+ return [textEditorErrorNode, editorContentErrorNode, paragraphNode$1, text(`Error: ${errorMessage}`), retryButtonNode, text(retry())];
7605
+ };
7606
+
7607
+ const formatFileSize = fileSize => {
7608
+ if (fileSize < 1024) {
7609
+ return `${fileSize} B`;
7610
+ }
7611
+ if (fileSize < 1024 * 1024) {
7612
+ return `${(fileSize / 1024).toFixed(2)} KB`;
7613
+ }
7614
+ return `${(fileSize / 1024 / 1024).toFixed(2)} MB`;
7615
+ };
7616
+ const button = (action, label, primary = false) => [{
7617
+ childCount: 1,
7618
+ className: mergeClassNames(Button, primary ? ButtonPrimary : ButtonSecondary),
7619
+ 'data-action': action,
7620
+ name: action,
7621
+ onClick: HandleClickAction,
7622
+ type: Button$2
7623
+ }, text(label)];
7624
+ const textEditorLargeFileNode = {
7625
+ childCount: 1,
7626
+ className: TextEditorLargeFile,
7627
+ type: Div
7628
+ };
7629
+ const editorContentLargeFileNode = {
7630
+ childCount: 3,
7631
+ className: EditorContentLargeFile,
7632
+ type: Div
7633
+ };
7634
+ const warningIconNode = {
7635
+ ariaHidden: true,
7636
+ childCount: 0,
7637
+ className: EditorLargeFileWarningIcon,
7638
+ type: Div
7639
+ };
7640
+ const paragraphNode = {
7641
+ childCount: 1,
7642
+ type: P
7643
+ };
7644
+ const actionsNode = {
7645
+ childCount: 4,
7646
+ className: EditorContentLargeFileActions,
7647
+ type: Div
7648
+ };
7649
+ const renderLargeFile = fileSize => {
7650
+ return [textEditorLargeFileNode, editorContentLargeFileNode, warningIconNode, paragraphNode, text(`${largeFileNotDisplayed()} (${formatFileSize(fileSize)}).`), actionsNode, ...button(OpenLargeFile, openAnyway(), true), ...button(ConfigureLargeFileLimit, configureLimit())];
7457
7651
  };
7458
7652
 
7459
7653
  const textEditorLoadingNode = {
@@ -7492,6 +7686,9 @@ const renderEditor = tab => {
7492
7686
  if (tab.loadingState === 'binary') {
7493
7687
  return renderBinary();
7494
7688
  }
7689
+ if (tab.loadingState === 'large' && tab.fileSize !== undefined) {
7690
+ return renderLargeFile(tab.fileSize);
7691
+ }
7495
7692
 
7496
7693
  // Viewlet is ready - render a reference node
7497
7694
  // Frontend will append the pre-created component at this position using the uid
@@ -8048,7 +8245,7 @@ const render2 = (uid, diffResult) => {
8048
8245
  const {
8049
8246
  newState,
8050
8247
  oldState
8051
- } = get(uid);
8248
+ } = get$1(uid);
8052
8249
  set$1(uid, newState, newState);
8053
8250
  const commands = applyRender(oldState, newState, diffResult);
8054
8251
  if (!isConnected()) {
@@ -8264,7 +8461,7 @@ const saveEditorAndHandleSettingsChange = async tab => {
8264
8461
  return editorState;
8265
8462
  };
8266
8463
  const getLatestStoredState = (uid, fallbackState, referenceTabId, referenceTabUri, allowMissingReference = false) => {
8267
- const stateFromStore = get(uid);
8464
+ const stateFromStore = get$1(uid);
8268
8465
  if (!stateFromStore) {
8269
8466
  return fallbackState;
8270
8467
  }
@@ -8619,7 +8816,7 @@ const resize = async (uid, dimensions) => {
8619
8816
  if (loading) {
8620
8817
  await loading;
8621
8818
  }
8622
- const instance = get(uid);
8819
+ const instance = get$1(uid);
8623
8820
  if (!instance) {
8624
8821
  return [];
8625
8822
  }
@@ -8713,7 +8910,7 @@ const commandMap = {
8713
8910
  'MainArea.handleTabsDragOver': wrapSerialCommand(handleTabsDragOver),
8714
8911
  'MainArea.handleTabsWheel': wrapSerialCommand(handleTabsWheel),
8715
8912
  'MainArea.handleTestWorkerMessagePort': handleTestWorkerMessagePort,
8716
- 'MainArea.handleUriChange': wrapSerialCommand(handleUriChange),
8913
+ 'MainArea.handleUriChange': wrapAsyncCommand(handleUriChangeWithContext),
8717
8914
  'MainArea.handleWorkspaceChange': wrapSerialCommand(handleWorkspaceChange),
8718
8915
  'MainArea.handleWorkspaceRefresh': wrapAsyncCommand(handleWorkspaceRefreshWithContext),
8719
8916
  'MainArea.hasActiveTextEditor': wrapGetter(hasActiveTextEditor),
@@ -8799,7 +8996,7 @@ const refreshFileIcons = async () => {
8799
8996
  const {
8800
8997
  newState,
8801
8998
  oldState
8802
- } = get(uid);
8999
+ } = get$1(uid);
8803
9000
  const updatedState = await handleIconThemeChange(newState);
8804
9001
  set$1(uid, oldState, updatedState);
8805
9002
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-area-worker",
3
- "version": "9.56.2",
3
+ "version": "9.58.0",
4
4
  "description": "Main Area Worker",
5
5
  "repository": {
6
6
  "type": "git",