@lvce-editor/editor-worker 19.69.10 → 19.70.1

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.
@@ -6381,7 +6381,7 @@ const diagnosticsEqual = (left, right) => {
6381
6381
  }
6382
6382
  return right.every((diagnostic, index) => {
6383
6383
  const other = left[index];
6384
- return other.code === diagnostic.code && other.columnIndex === diagnostic.columnIndex && other.endColumnIndex === diagnostic.endColumnIndex && other.endRowIndex === diagnostic.endRowIndex && other.message === diagnostic.message && other.rowIndex === diagnostic.rowIndex && other.source === diagnostic.source && other.type === diagnostic.type && other.uri === diagnostic.uri;
6384
+ return other.code === diagnostic.code && other.columnIndex === diagnostic.columnIndex && other.endColumnIndex === diagnostic.endColumnIndex && other.endRowIndex === diagnostic.endRowIndex && other.message === diagnostic.message && other.rowIndex === diagnostic.rowIndex && other.source === diagnostic.source && (other.tags === diagnostic.tags || (other.tags?.length ?? 0) === (diagnostic.tags?.length ?? 0) && (other.tags ?? []).every((tag, index) => tag === diagnostic.tags?.[index])) && other.type === diagnostic.type && other.uri === diagnostic.uri;
6385
6385
  });
6386
6386
  };
6387
6387
  const diagnosticLayoutEqual = (left, right) => left.charWidth === right.charWidth && left.deltaY === right.deltaY && left.fontFamily === right.fontFamily && left.fontSize === right.fontSize && left.fontWeight === right.fontWeight && left.isMonospaceFont === right.isMonospaceFont && left.itemHeight === right.itemHeight && left.letterSpacing === right.letterSpacing && left.lines === right.lines && left.minLineY === right.minLineY && left.rowHeight === right.rowHeight && left.tabSize === right.tabSize && left.viewLineIndices === right.viewLineIndices && left.width === right.width;
@@ -6438,7 +6438,11 @@ const saveProviderResults = (editor, providers) => {
6438
6438
  uri: editor.uri
6439
6439
  });
6440
6440
  };
6441
- const updateDiagnostics = async editor => {
6441
+ const updateDiagnostics = async (editor, timeoutMs = 0) => {
6442
+ const strict = timeoutMs > 0;
6443
+ if (strict && editor.loadError) {
6444
+ throw new Error(`Cannot await diagnostics: ${editor.loadError}`);
6445
+ }
6442
6446
  if (!editor.diagnosticsEnabled || editor.loadError) {
6443
6447
  return editor;
6444
6448
  }
@@ -6459,13 +6463,22 @@ const updateDiagnostics = async editor => {
6459
6463
  const completed = Promise.withResolvers();
6460
6464
  let commitQueue = Promise.resolve();
6461
6465
  let providerCount = -1;
6466
+ let finished = false;
6467
+ const receivedProviders = new Set();
6468
+ const timeout = strict ? setTimeout(() => completed.reject(new Error(`Diagnostics timed out after ${timeoutMs}ms for ${editor.uri}`)), timeoutMs) : undefined;
6462
6469
  port1.onmessage = event => {
6463
6470
  const previousCommit = commitQueue;
6464
6471
  commitQueue = (async () => {
6465
6472
  await previousCommit;
6466
6473
  try {
6474
+ if (finished) {
6475
+ return;
6476
+ }
6467
6477
  const message = event.data;
6468
6478
  if (requestGenerations.get(editor.id) !== generation) {
6479
+ if (strict) {
6480
+ throw new Error('Diagnostics request was superseded');
6481
+ }
6469
6482
  if (message.type === 'done') {
6470
6483
  port1.close();
6471
6484
  completed.resolve();
@@ -6492,6 +6505,10 @@ const updateDiagnostics = async editor => {
6492
6505
  return;
6493
6506
  }
6494
6507
  if (message.type === 'result' && message.providerId !== undefined) {
6508
+ if (strict && message.error !== undefined) {
6509
+ throw new Error(`Diagnostic provider ${message.providerId} failed: ${message.error}`);
6510
+ }
6511
+ receivedProviders.add(message.providerId);
6495
6512
  providers.set(message.providerId, {
6496
6513
  diagnostics: message.diagnostics ?? [],
6497
6514
  providerIndex: message.providerIndex ?? providers.size
@@ -6500,6 +6517,9 @@ const updateDiagnostics = async editor => {
6500
6517
  return;
6501
6518
  }
6502
6519
  if (message.type === 'done') {
6520
+ if (strict && (providerCount < 0 || receivedProviders.size !== providerCount)) {
6521
+ throw new Error('Diagnostics stream ended without all provider results');
6522
+ }
6503
6523
  if (providerCount === 0) {
6504
6524
  providers.clear();
6505
6525
  await commitDiagnostics(editor, generation, [], () => saveProviderResults(editor, providers));
@@ -6512,15 +6532,25 @@ const updateDiagnostics = async editor => {
6512
6532
  }
6513
6533
  } catch (error) {
6514
6534
  port1.close();
6515
- completed.resolve();
6516
- await handleError(error, editor);
6535
+ if (strict) {
6536
+ completed.reject(error);
6537
+ } else {
6538
+ completed.resolve();
6539
+ await handleError(error, editor);
6540
+ }
6517
6541
  }
6518
6542
  })();
6519
6543
  };
6520
6544
  port1.start();
6521
- try {
6545
+ const request = async () => {
6522
6546
  const response = await getDiagnostics$1(editor, port2);
6547
+ if (finished) {
6548
+ return;
6549
+ }
6523
6550
  if (Array.isArray(response) && providerCount === -1) {
6551
+ if (strict) {
6552
+ throw new Error('Diagnostic provider does not support completion and error reporting');
6553
+ }
6524
6554
  providers.set('legacy', {
6525
6555
  diagnostics: response,
6526
6556
  providerIndex: 0
@@ -6529,12 +6559,27 @@ const updateDiagnostics = async editor => {
6529
6559
  port1.close();
6530
6560
  completed.resolve();
6531
6561
  }
6532
- await completed.promise;
6562
+ };
6563
+ try {
6564
+ await Promise.all([request(), completed.promise]);
6533
6565
  const latest = get$8(editor.id);
6566
+ if (strict && !isApplicable(latest, editor, generation)) {
6567
+ throw new Error('Editor changed or closed while waiting for diagnostics');
6568
+ }
6534
6569
  return isApplicable(latest, editor, generation) ? latest.newState : editor;
6535
6570
  } catch (error) {
6536
- port1.close();
6571
+ if (strict) {
6572
+ if (requestGenerations.get(editor.id) === generation) {
6573
+ requestGenerations.set(editor.id, generation + 1);
6574
+ }
6575
+ throw error;
6576
+ }
6537
6577
  return handleError(error, editor);
6578
+ } finally {
6579
+ finished = true;
6580
+ clearTimeout(timeout);
6581
+ port1.close();
6582
+ port2.close();
6538
6583
  }
6539
6584
  };
6540
6585
  const requestDiagnostics = editor => {
@@ -6555,6 +6600,18 @@ const updateDiagnosticsAll = async () => {
6555
6600
  }
6556
6601
  };
6557
6602
 
6603
+ // Do not wrap this command in EditorCommandQueue: streamed results need that queue to commit.
6604
+ const waitForDiagnostics = async (editorId, timeoutMs = 30_000) => {
6605
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 300_000) {
6606
+ throw new Error('Diagnostics timeout must be between 1 and 300000ms');
6607
+ }
6608
+ const editor = get$8(editorId)?.newState;
6609
+ if (!editor || editor.initial) {
6610
+ throw new Error(`Editor is not ready: ${editorId}`);
6611
+ }
6612
+ await updateDiagnostics(editor, timeoutMs);
6613
+ };
6614
+
6558
6615
  const disposeEditor = async editorUid => {
6559
6616
  const editor = get$8(editorUid)?.newState;
6560
6617
  if (!editor) {
@@ -13149,11 +13206,21 @@ const getSnippetChanges = (lines, selections, snippet) => {
13149
13206
  for (let i = 0; i < selections.length; i += 4) {
13150
13207
  const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn] = getSelectionPairs(selections, i);
13151
13208
  if (insertedLines.length > 1) {
13209
+ let placeholderRow = -1;
13210
+ let placeholderColumn = -1;
13211
+ const insertedLinesWithoutPlaceholder = insertedLines.map((line, rowIndex) => {
13212
+ const index = line.indexOf('$0');
13213
+ if (index !== -1 && placeholderRow === -1) {
13214
+ placeholderRow = rowIndex;
13215
+ placeholderColumn = index;
13216
+ }
13217
+ return line.replace('$0', '');
13218
+ });
13152
13219
  const line = getLine$1({
13153
13220
  lines
13154
13221
  }, selectionStartRow);
13155
13222
  const indent = getIndent(line);
13156
- const insertedLinesHere = [insertedLines[0], ...insertedLines.slice(1).map(line => indent + line)];
13223
+ const insertedLinesHere = [insertedLinesWithoutPlaceholder[0], ...insertedLinesWithoutPlaceholder.slice(1).map(line => indent + line)];
13157
13224
  const deleted = [''];
13158
13225
  changes.push({
13159
13226
  deleted,
@@ -13169,11 +13236,17 @@ const getSnippetChanges = (lines, selections, snippet) => {
13169
13236
  }
13170
13237
  });
13171
13238
  const lastInsertedLine = insertedLines.at(-1);
13172
- selectionChanges.push(selectionEndRow + insertedLines.length - deleted.length,
13173
- // @ts-ignore
13174
- selectionEndColumn + lastInsertedLine.length, selectionEndRow + insertedLines.length - deleted.length,
13175
- // @ts-ignore
13176
- selectionEndColumn + lastInsertedLine.length);
13239
+ if (placeholderRow === -1) {
13240
+ selectionChanges.push(selectionEndRow + insertedLines.length - deleted.length,
13241
+ // @ts-ignore
13242
+ selectionEndColumn + lastInsertedLine.length, selectionEndRow + insertedLines.length - deleted.length,
13243
+ // @ts-ignore
13244
+ selectionEndColumn + lastInsertedLine.length);
13245
+ } else {
13246
+ const cursorRow = selectionStartRow + placeholderRow;
13247
+ const cursorColumn = placeholderColumn + (placeholderRow === 0 ? selectionStartColumn - snippet.deleted : indent.length);
13248
+ selectionChanges.push(cursorRow, cursorColumn, cursorRow, cursorColumn);
13249
+ }
13177
13250
  } else {
13178
13251
  const line = insertedLines[0];
13179
13252
  const placeholderIndex = line.indexOf('$0');
@@ -16720,6 +16793,10 @@ const getEditorDiagnosticsVirtualDom = (diagnostics, bracketMatchInfos = []) =>
16720
16793
  }, ...diagnosticsDom, ...bracketMatchesDom];
16721
16794
  };
16722
16795
 
16796
+ const DiagnosticTag = {
16797
+ Unnecessary: 1
16798
+ };
16799
+
16723
16800
  const editorLineDecorationNode = {
16724
16801
  childCount: 1,
16725
16802
  className: EditorLineDecoration,
@@ -16735,6 +16812,49 @@ const mergeConflictActions = [{
16735
16812
  action: 'both',
16736
16813
  label: 'Accept Both Changes'
16737
16814
  }];
16815
+ const getUnnecessaryRanges = (diagnostics, rowIndex, textLength) => {
16816
+ return diagnostics.filter(diagnostic => diagnostic.tags?.includes(DiagnosticTag.Unnecessary)).flatMap(diagnostic => {
16817
+ if (rowIndex < diagnostic.rowIndex || rowIndex > diagnostic.endRowIndex) {
16818
+ return [];
16819
+ }
16820
+ const start = rowIndex === diagnostic.rowIndex ? diagnostic.columnIndex : 0;
16821
+ const end = rowIndex === diagnostic.endRowIndex ? diagnostic.endColumnIndex : textLength;
16822
+ return start < end ? [{
16823
+ end,
16824
+ start
16825
+ }] : [];
16826
+ }).toSorted((left, right) => left.start - right.start);
16827
+ };
16828
+ const getTokenParts = (textInfos, ranges) => {
16829
+ const parts = [];
16830
+ let offset = 0;
16831
+ for (let index = 0; index < textInfos.length; index += 2) {
16832
+ const tokenText = textInfos[index];
16833
+ const tokenClassName = textInfos[index + 1];
16834
+ const tokenEnd = offset + tokenText.length;
16835
+ const boundaries = new Set([offset, tokenEnd]);
16836
+ for (const range of ranges) {
16837
+ if (range.start > offset && range.start < tokenEnd) {
16838
+ boundaries.add(range.start);
16839
+ }
16840
+ if (range.end > offset && range.end < tokenEnd) {
16841
+ boundaries.add(range.end);
16842
+ }
16843
+ }
16844
+ const sortedBoundaries = [...boundaries].toSorted((left, right) => left - right);
16845
+ for (let boundaryIndex = 0; boundaryIndex < sortedBoundaries.length - 1; boundaryIndex++) {
16846
+ const start = sortedBoundaries[boundaryIndex];
16847
+ const end = sortedBoundaries[boundaryIndex + 1];
16848
+ const unnecessary = ranges.some(range => start >= range.start && end <= range.end);
16849
+ parts.push({
16850
+ className: unnecessary ? mergeClassNames(tokenClassName, 'EditorTokenUnnecessary') : tokenClassName,
16851
+ text: tokenText.slice(start - offset, end - offset)
16852
+ });
16853
+ }
16854
+ offset = tokenEnd;
16855
+ }
16856
+ return parts;
16857
+ };
16738
16858
  const addMergeConflictActions = (dom, rowIndex) => {
16739
16859
  dom.push({
16740
16860
  childCount: mergeConflictActions.length,
@@ -16759,7 +16879,7 @@ const addMergeConflictActions = (dom, rowIndex) => {
16759
16879
  }, text(label));
16760
16880
  }
16761
16881
  };
16762
- const getEditorRowsVirtualDom$1 = (textInfos, differences, lineNumbers = true, highlightedLine = -1, visibleLineIndices = [], endOfLineDecorations = [], visibleViewLineIndices = [], problemsHighlightedRow = -1) => {
16882
+ const getEditorRowsVirtualDom$1 = (textInfos, differences, lineNumbers = true, highlightedLine = -1, visibleLineIndices = [], endOfLineDecorations = [], visibleViewLineIndices = [], problemsHighlightedRow = -1, diagnostics = []) => {
16763
16883
  const dom = [];
16764
16884
  const actualViewRows = visibleViewLineIndices.length === 0 ? Array.from({
16765
16885
  length: textInfos.length
@@ -16774,6 +16894,11 @@ const getEditorRowsVirtualDom$1 = (textInfos, differences, lineNumbers = true, h
16774
16894
  const difference = differences[textInfoIndex];
16775
16895
  const rowIndex = viewRow;
16776
16896
  const rowDecorations = endOfLineDecorations.filter(decoration => decoration.rowIndex === rowIndex);
16897
+ let rowTextLength = 0;
16898
+ for (let index = 0; index < textInfo.length; index += 2) {
16899
+ rowTextLength += textInfo[index].length;
16900
+ }
16901
+ const tokenParts = getTokenParts(textInfo, getUnnecessaryRanges(diagnostics, rowIndex, rowTextLength));
16777
16902
  let className = EditorRow;
16778
16903
  if (rowIndex === highlightedLine) {
16779
16904
  className = mergeClassNames(className, EditorRowHighlighted);
@@ -16782,14 +16907,15 @@ const getEditorRowsVirtualDom$1 = (textInfos, differences, lineNumbers = true, h
16782
16907
  className = mergeClassNames(className, 'EditorProblemsHighlightedRow');
16783
16908
  }
16784
16909
  dom.push({
16785
- childCount: textInfo.length / 2 + rowDecorations.length,
16910
+ childCount: tokenParts.length + rowDecorations.length,
16786
16911
  className,
16787
16912
  translate: difference === 0 ? '' : px(difference),
16788
16913
  type: Div
16789
16914
  });
16790
- for (let j = 0; j < textInfo.length; j += 2) {
16791
- const tokenText = textInfo[j];
16792
- const className = textInfo[j + 1];
16915
+ for (const {
16916
+ className,
16917
+ text: tokenText
16918
+ } of tokenParts) {
16793
16919
  dom.push({
16794
16920
  childCount: 1,
16795
16921
  className,
@@ -17559,6 +17685,7 @@ const renderLines = {
17559
17685
  return [/* method */'setIncrementalEdits', /* incrementalEdits */incrementalEdits];
17560
17686
  }
17561
17687
  const {
17688
+ diagnostics,
17562
17689
  differences,
17563
17690
  endOfLineDecorations,
17564
17691
  textInfos
@@ -17569,7 +17696,7 @@ const renderLines = {
17569
17696
  visibleLineIndices,
17570
17697
  visibleViewLineIndices
17571
17698
  } = newState;
17572
- const dom = getEditorRowsVirtualDom$1(textInfos, differences, true, highlightedLine, visibleLineIndices, endOfLineDecorations, visibleViewLineIndices, newState.problemsHighlightedRow);
17699
+ const dom = getEditorRowsVirtualDom$1(textInfos, differences, true, highlightedLine, visibleLineIndices, endOfLineDecorations, visibleViewLineIndices, newState.problemsHighlightedRow, diagnostics || []);
17573
17700
  return [/* method */'setText', dom];
17574
17701
  },
17575
17702
  isEqual: (oldState, newState) => oldState.lines === newState.lines && oldState.foldingRanges === newState.foldingRanges && oldState.visibleViewLineIndices === newState.visibleViewLineIndices && oldState.tokenizerId === newState.tokenizerId && oldState.minLineY === newState.minLineY && oldState.decorations === newState.decorations && oldState.embeds === newState.embeds && oldState.endOfLineDecorations === newState.endOfLineDecorations && oldState.deltaX === newState.deltaX && oldState.width === newState.width && oldState.highlightedLine === newState.highlightedLine && oldState.problemsHighlightedRow === newState.problemsHighlightedRow && oldState.debugEnabled === newState.debugEnabled
@@ -18264,6 +18391,7 @@ const commandMap = {
18264
18391
  'Editor.updateDebugInfo': updateDebugInfo,
18265
18392
  'Editor.updateDiagnostics': wrapCommand(requestDiagnostics),
18266
18393
  'Editor.updateDiagnosticsAll': updateDiagnosticsAll,
18394
+ 'Editor.waitForDiagnostics': waitForDiagnostics,
18267
18395
  'EditorCompletion.close': close$3,
18268
18396
  'EditorCompletion.closeDetails': closeDetails$1,
18269
18397
  'EditorCompletion.focusFirst': focusFirst$1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/editor-worker",
3
- "version": "19.69.10",
3
+ "version": "19.70.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git@github.com:lvce-editor/editor-worker.git"