stream-monaco 0.0.41 → 0.0.44

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.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_preloadMonacoWorkers_shared = require('./preloadMonacoWorkers.shared-BT4GsCRM.cjs');
1
+ const require_preloadMonacoWorkers_shared = require('./preloadMonacoWorkers.shared-DpwiD-Ro.cjs');
2
2
 
3
3
  //#region src/ensureMonacoWorkers.ts
4
4
  function ensureMonacoWorkers() {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { RevealStrategy, clearHighlighterCache, defaultRevealDebounceMs, detectLanguage, editorWorkerPath, getOrCreateHighlighter, registerMonacoThemes, uniqueWorkerPaths, useMonaco, workerPathByLabel } from "./preloadMonacoWorkers.shared-CtSx-xKA.js";
1
+ import { RevealStrategy, clearHighlighterCache, defaultRevealDebounceMs, detectLanguage, editorWorkerPath, getOrCreateHighlighter, registerMonacoThemes, uniqueWorkerPaths, useMonaco, workerPathByLabel } from "./preloadMonacoWorkers.shared-vZJruB3t.js";
2
2
 
3
3
  //#region src/ensureMonacoWorkers.ts
4
4
  function ensureMonacoWorkers() {
@@ -1,4 +1,4 @@
1
- const require_preloadMonacoWorkers_shared = require('./preloadMonacoWorkers.shared-BT4GsCRM.cjs');
1
+ const require_preloadMonacoWorkers_shared = require('./preloadMonacoWorkers.shared-DpwiD-Ro.cjs');
2
2
  const monaco_editor_esm_vs_basic_languages_cpp_cpp = require_preloadMonacoWorkers_shared.__toESM(require("monaco-editor/esm/vs/basic-languages/cpp/cpp"));
3
3
  const monaco_editor_esm_vs_basic_languages_javascript_javascript = require_preloadMonacoWorkers_shared.__toESM(require("monaco-editor/esm/vs/basic-languages/javascript/javascript"));
4
4
  const monaco_editor_esm_vs_basic_languages_powershell_powershell = require_preloadMonacoWorkers_shared.__toESM(require("monaco-editor/esm/vs/basic-languages/powershell/powershell"));
@@ -1,4 +1,4 @@
1
- import { RevealStrategy, clearHighlighterCache, defaultRevealDebounceMs, detectLanguage, getOrCreateHighlighter, monaco_shim_exports, processedLanguage, registerMonacoThemes, useMonaco, workerPathByLabel } from "./preloadMonacoWorkers.shared-CtSx-xKA.js";
1
+ import { RevealStrategy, clearHighlighterCache, defaultRevealDebounceMs, detectLanguage, getOrCreateHighlighter, monaco_shim_exports, processedLanguage, registerMonacoThemes, useMonaco, workerPathByLabel } from "./preloadMonacoWorkers.shared-vZJruB3t.js";
2
2
  import { conf, language } from "monaco-editor/esm/vs/basic-languages/cpp/cpp";
3
3
  import { conf as conf$1, language as language$1 } from "monaco-editor/esm/vs/basic-languages/javascript/javascript";
4
4
  import { conf as conf$2, language as language$2 } from "monaco-editor/esm/vs/basic-languages/powershell/powershell";
@@ -527,6 +527,14 @@ function createScrollWatcherForEditor(ed, opts) {
527
527
  return api;
528
528
  }
529
529
 
530
+ //#endregion
531
+ //#region src/utils/textChunks.ts
532
+ function countLineBreaks(text) {
533
+ let count = 0;
534
+ for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) count += 1;
535
+ return count;
536
+ }
537
+
530
538
  //#endregion
531
539
  //#region src/core/diffAppearance.ts
532
540
  function parseCssColorRgb(color) {
@@ -4116,6 +4124,8 @@ var DiffEditorManager = class DiffEditorManager {
4116
4124
  this.createDomDisposable(this.diffHunkDisposables, this.diffHunkUpperNode, "mouseleave", () => this.scheduleHideDiffHunkActions());
4117
4125
  this.createDomDisposable(this.diffHunkDisposables, this.diffHunkLowerNode, "mouseenter", () => this.cancelScheduledHideDiffHunkActions());
4118
4126
  this.createDomDisposable(this.diffHunkDisposables, this.diffHunkLowerNode, "mouseleave", () => this.scheduleHideDiffHunkActions());
4127
+ this.createDomDisposable(this.diffHunkDisposables, this.diffHunkUpperNode, "wheel", (event) => this.handleDiffHunkWheel(event, "upper"));
4128
+ this.createDomDisposable(this.diffHunkDisposables, this.diffHunkLowerNode, "wheel", (event) => this.handleDiffHunkWheel(event, "lower"));
4119
4129
  overlay.append(this.diffHunkUpperNode, this.diffHunkLowerNode);
4120
4130
  const originalEditor = this.diffEditorView.getOriginalEditor();
4121
4131
  const modifiedEditor = this.diffEditorView.getModifiedEditor();
@@ -4139,6 +4149,17 @@ var DiffEditorManager = class DiffEditorManager {
4139
4149
  }));
4140
4150
  this.diffHunkLineChanges = this.getEffectiveLineChanges();
4141
4151
  }
4152
+ handleDiffHunkWheel(event, side) {
4153
+ var _editor$setScrollLeft, _editor$getScrollLeft, _editor$setScrollTop, _editor$getScrollTop2;
4154
+ if (Math.abs(event.deltaX) < .5 && Math.abs(event.deltaY) < .5) return;
4155
+ if (!this.diffEditorView) return;
4156
+ const editor = this.isDiffInlineMode() || side === "lower" ? this.diffEditorView.getModifiedEditor() : this.diffEditorView.getOriginalEditor();
4157
+ event.preventDefault();
4158
+ event.stopPropagation();
4159
+ (_editor$setScrollLeft = editor.setScrollLeft) === null || _editor$setScrollLeft === void 0 || _editor$setScrollLeft.call(editor, (((_editor$getScrollLeft = editor.getScrollLeft) === null || _editor$getScrollLeft === void 0 ? void 0 : _editor$getScrollLeft.call(editor)) ?? 0) + event.deltaX);
4160
+ (_editor$setScrollTop = editor.setScrollTop) === null || _editor$setScrollTop === void 0 || _editor$setScrollTop.call(editor, (((_editor$getScrollTop2 = editor.getScrollTop) === null || _editor$getScrollTop2 === void 0 ? void 0 : _editor$getScrollTop2.call(editor)) ?? 0) + event.deltaY);
4161
+ this.hideDiffHunkActions();
4162
+ }
4142
4163
  cancelScheduledHideDiffHunkActions() {
4143
4164
  if (this.diffHunkHideTimer != null) {
4144
4165
  clearTimeout(this.diffHunkHideTimer);
@@ -4418,9 +4439,10 @@ var DiffEditorManager = class DiffEditorManager {
4418
4439
  shouldAutoScrollDiff: this.shouldAutoScrollDiff
4419
4440
  });
4420
4441
  if (!this.diffEditorView) return;
4442
+ if (!(this.diffAutoScroll && this.autoScrollOnUpdate && this.shouldAutoScrollDiff)) return;
4421
4443
  const hasV = this.hasVerticalScrollbarModified();
4422
4444
  log("diff", "hasVerticalScrollbarModified ->", hasV);
4423
- if (!(this.diffAutoScroll && this.autoScrollOnUpdate && this.shouldAutoScrollDiff && hasV)) return;
4445
+ if (!hasV) return;
4424
4446
  const me = this.diffEditorView.getModifiedEditor();
4425
4447
  const model = me.getModel();
4426
4448
  const currentLine = (model === null || model === void 0 ? void 0 : model.getLineCount()) ?? 1;
@@ -4642,7 +4664,7 @@ var DiffEditorManager = class DiffEditorManager {
4642
4664
  this.diffComputedVersions = null;
4643
4665
  this.diffPresentationDisposables.push(this.diffEditorView.onDidUpdateDiff(() => {
4644
4666
  this.diffComputedVersions = this.captureCurrentDiffVersions();
4645
- this.syncDiffEditorLayoutToContainer();
4667
+ this.scheduleSyncDiffEditorLayoutToContainer();
4646
4668
  this.scheduleSyncDiffPresentationDecorations();
4647
4669
  }));
4648
4670
  this.diffPresentationDisposables.push(oEditor.onDidChangeModelContent(() => {
@@ -4807,6 +4829,7 @@ var DiffEditorManager = class DiffEditorManager {
4807
4829
  }
4808
4830
  updateModified(newCode, codeLanguage) {
4809
4831
  if (!this.diffEditorView || !this.modifiedModel) return;
4832
+ this.syncLastKnownModified();
4810
4833
  if (codeLanguage) {
4811
4834
  const lang = processedLanguage(codeLanguage);
4812
4835
  if (lang && this.modifiedModel.getLanguageId() !== lang) monaco_shim_exports.editor.setModelLanguage(this.modifiedModel, lang);
@@ -4819,7 +4842,7 @@ var DiffEditorManager = class DiffEditorManager {
4819
4842
  if (tailAppend) this.appendModified(newCode.slice(prev.length), codeLanguage);
4820
4843
  else {
4821
4844
  this.flushModifiedAppendBufferSync();
4822
- const prevAfterFlush = this.modifiedModel.getValue();
4845
+ const prevAfterFlush = this.lastKnownModifiedCode ?? this.modifiedModel.getValue();
4823
4846
  const prevLine = this.modifiedModel.getLineCount();
4824
4847
  this.applyMinimalEditToModel(this.modifiedModel, prevAfterFlush, newCode);
4825
4848
  const newLine = this.modifiedModel.getLineCount();
@@ -5069,6 +5092,7 @@ var DiffEditorManager = class DiffEditorManager {
5069
5092
  }
5070
5093
  const { original, modified, lang } = this.pendingDiffUpdate;
5071
5094
  this.pendingDiffUpdate = null;
5095
+ this.syncLastKnownModified();
5072
5096
  this.flushOriginalAppendBufferSync();
5073
5097
  this.flushModifiedAppendBufferSync();
5074
5098
  if (lang) {
@@ -5089,7 +5113,7 @@ var DiffEditorManager = class DiffEditorManager {
5089
5113
  else this.applyMinimalEditToModel(o, prevO, original);
5090
5114
  this.lastKnownOriginalCode = original;
5091
5115
  }
5092
- const prevM = m.getValue();
5116
+ const prevM = this.lastKnownModifiedCode;
5093
5117
  const prevMLineCount = m.getLineCount();
5094
5118
  const modifiedTailAppend = prevM !== modified && modified.startsWith(prevM) && prevM.length < modified.length;
5095
5119
  const hasContentChange = prevO !== original || prevM !== modified;
@@ -5130,6 +5154,33 @@ var DiffEditorManager = class DiffEditorManager {
5130
5154
  this.preserveNativeDiffDecorationsOnStaleAppend = true;
5131
5155
  this.appendToModel(this.modifiedModel, text);
5132
5156
  }
5157
+ splitAppendTextForProgressiveFlush(text, maxChunkChars = 12e3, maxChunkLines = 200) {
5158
+ if (!text || text.length <= maxChunkChars) return [text];
5159
+ const chunks = [];
5160
+ let start = 0;
5161
+ let lineCount = 0;
5162
+ let lastSafeEnd = 0;
5163
+ for (let i = 0; i < text.length; i++) {
5164
+ if (text.charCodeAt(i) === 10) {
5165
+ lineCount += 1;
5166
+ lastSafeEnd = i + 1;
5167
+ }
5168
+ if (i - start + 1 < maxChunkChars && lineCount < maxChunkLines) continue;
5169
+ let end = lastSafeEnd > start ? lastSafeEnd : i + 1;
5170
+ if (end < text.length) {
5171
+ const prev = text.charCodeAt(end - 1);
5172
+ const next = text.charCodeAt(end);
5173
+ if (prev >= 55296 && prev <= 56319 && next >= 56320 && next <= 57343) end += 1;
5174
+ }
5175
+ chunks.push(text.slice(start, end));
5176
+ start = end;
5177
+ i = end - 1;
5178
+ lineCount = 0;
5179
+ lastSafeEnd = start;
5180
+ }
5181
+ if (start < text.length) chunks.push(text.slice(start));
5182
+ return chunks.length ? chunks : [text];
5183
+ }
5133
5184
  async flushAppendBufferDiff() {
5134
5185
  if (!this.diffEditorView) return;
5135
5186
  if (this.appendBufferOriginalDiff.length === 0 && this.appendBufferModifiedDiff.length === 0) return;
@@ -5150,17 +5201,16 @@ var DiffEditorManager = class DiffEditorManager {
5150
5201
  return;
5151
5202
  }
5152
5203
  let parts = this.appendBufferModifiedDiff.splice(0);
5204
+ if (parts.length === 0) {
5205
+ this.eagerlyGrowDiffContainerHeight();
5206
+ return;
5207
+ }
5153
5208
  const prevLineInit = model.getLineCount();
5154
5209
  const totalText = parts.join("");
5155
5210
  const totalChars = totalText.length;
5156
- if (parts.length === 1 && totalChars > 5e3) {
5157
- const lines = totalText.split(/\r?\n/);
5158
- const chunkSize = 200;
5159
- const chunks = [];
5160
- for (let i = 0; i < lines.length; i += chunkSize) chunks.push(`${lines.slice(i, i + chunkSize).join("\n")}\n`);
5161
- if (chunks.length > 1) parts = chunks;
5162
- }
5163
- const applyChunked = parts.length > 1 && (totalChars > 2e3 || model.getLineCount && model.getLineCount() + 0 - prevLineInit > 50);
5211
+ const totalLineBreaks = countLineBreaks(totalText);
5212
+ if (parts.length === 1 && totalChars > 5e3) parts = this.splitAppendTextForProgressiveFlush(totalText);
5213
+ const applyChunked = parts.length > 1 && (totalChars > 2e3 || totalLineBreaks > 50);
5164
5214
  log("diff", "flushAppendBufferDiff start", {
5165
5215
  partsCount: parts.length,
5166
5216
  totalChars,
@@ -5179,6 +5229,8 @@ var DiffEditorManager = class DiffEditorManager {
5179
5229
  } catch {}
5180
5230
  if (applyChunked) {
5181
5231
  log("diff", "flushAppendBufferDiff applying chunked", { partsLen: parts.length });
5232
+ if (this.lastKnownModifiedCode == null) this.lastKnownModifiedCode = model.getValue();
5233
+ let currentLength = this.lastKnownModifiedCode.length;
5182
5234
  let idx = 0;
5183
5235
  for (const part of parts) {
5184
5236
  if (!part) continue;
@@ -5188,17 +5240,9 @@ var DiffEditorManager = class DiffEditorManager {
5188
5240
  partLen: part.length,
5189
5241
  prevLine
5190
5242
  });
5191
- const lastColumn$1 = model.getLineMaxColumn(prevLine);
5192
- const range$1 = new monaco_shim_exports.Range(prevLine, lastColumn$1, prevLine, lastColumn$1);
5193
5243
  this.preserveNativeDiffDecorationsOnStaleAppend = true;
5194
- this.runAsProgrammaticModifiedContentChange(() => {
5195
- model.applyEdits([{
5196
- range: range$1,
5197
- text: part,
5198
- forceMoveMarkers: true
5199
- }]);
5200
- });
5201
- this.lastKnownModifiedCode = model.getValue();
5244
+ this.appendToModel(model, part, currentLength);
5245
+ currentLength += part.length;
5202
5246
  const newLine$1 = model.getLineCount();
5203
5247
  this.lastKnownModifiedLineCount = newLine$1;
5204
5248
  await new Promise((resolve) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(resolve) : setTimeout(resolve, 0));
@@ -5224,23 +5268,15 @@ var DiffEditorManager = class DiffEditorManager {
5224
5268
  newLine: newLine$1
5225
5269
  });
5226
5270
  }
5271
+ this.lastKnownModifiedCode = model.getValue();
5227
5272
  if (suppressedByFlush) watcherApi.setSuppressed(false);
5228
5273
  return;
5229
5274
  }
5230
5275
  const text = totalText;
5231
5276
  this.appendBufferModifiedDiff.length = 0;
5232
5277
  prevLine = model.getLineCount();
5233
- const lastColumn = model.getLineMaxColumn(prevLine);
5234
- const range = new monaco_shim_exports.Range(prevLine, lastColumn, prevLine, lastColumn);
5235
5278
  this.preserveNativeDiffDecorationsOnStaleAppend = true;
5236
- this.runAsProgrammaticModifiedContentChange(() => {
5237
- model.applyEdits([{
5238
- range,
5239
- text,
5240
- forceMoveMarkers: true
5241
- }]);
5242
- });
5243
- this.lastKnownModifiedCode = model.getValue();
5279
+ this.appendToModel(model, text);
5244
5280
  const newLine = model.getLineCount();
5245
5281
  this.lastKnownModifiedLineCount = newLine;
5246
5282
  this.eagerlyGrowDiffContainerHeight();
@@ -5283,8 +5319,30 @@ var DiffEditorManager = class DiffEditorManager {
5283
5319
  });
5284
5320
  if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
5285
5321
  }
5286
- appendToModel(model, appendText) {
5322
+ getModelValueLength(model) {
5323
+ const getValueLength = model.getValueLength;
5324
+ if (typeof getValueLength === "function") try {
5325
+ return getValueLength.call(model);
5326
+ } catch {}
5327
+ return model.getValue().length;
5328
+ }
5329
+ mergeKnownAppend(known, appendText, previousLength, model) {
5330
+ if (known == null) return model.getValue();
5331
+ const nextLength = previousLength + appendText.length;
5332
+ if (known.length === previousLength) return known + appendText;
5333
+ if (known.length >= nextLength && known.slice(previousLength, nextLength) === appendText) return known;
5334
+ return model.getValue();
5335
+ }
5336
+ syncKnownCodeAfterAppend(model, appendText, previousLength) {
5337
+ if (model === this.originalModel) {
5338
+ this.lastKnownOriginalCode = this.mergeKnownAppend(this.lastKnownOriginalCode, appendText, previousLength, model);
5339
+ return;
5340
+ }
5341
+ if (model === this.modifiedModel) this.lastKnownModifiedCode = this.mergeKnownAppend(this.lastKnownModifiedCode, appendText, previousLength, model);
5342
+ }
5343
+ appendToModel(model, appendText, knownLength) {
5287
5344
  if (!appendText) return;
5345
+ const previousLength = knownLength != null ? knownLength : this.getModelValueLength(model);
5288
5346
  const lastLine = model.getLineCount();
5289
5347
  const lastColumn = model.getLineMaxColumn(lastLine);
5290
5348
  const range = new monaco_shim_exports.Range(lastLine, lastColumn, lastLine, lastColumn);
@@ -5296,6 +5354,7 @@ var DiffEditorManager = class DiffEditorManager {
5296
5354
  }]);
5297
5355
  });
5298
5356
  if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
5357
+ this.syncKnownCodeAfterAppend(model, appendText, previousLength);
5299
5358
  }
5300
5359
  applyModelEdit(model, fn) {
5301
5360
  if (model === this.modifiedModel) {
@@ -5333,6 +5392,8 @@ var EditorManager = class {
5333
5392
  minimalEditMaxChangeRatioValue = minimalEditMaxChangeRatio;
5334
5393
  lastUpdateFlushTime = 0;
5335
5394
  updateThrottleTimer = null;
5395
+ lastAppendFlushTime = 0;
5396
+ appendFlushThrottleTimer = null;
5336
5397
  shouldAutoScroll = true;
5337
5398
  scrollWatcher = null;
5338
5399
  scrollWatcherSuppressionTimer = null;
@@ -5432,6 +5493,10 @@ var EditorManager = class {
5432
5493
  clearTimeout(this.updateThrottleTimer);
5433
5494
  this.updateThrottleTimer = null;
5434
5495
  }
5496
+ if (this.appendFlushThrottleTimer != null) {
5497
+ clearTimeout(this.appendFlushThrottleTimer);
5498
+ this.appendFlushThrottleTimer = null;
5499
+ }
5435
5500
  }
5436
5501
  initDebugFlag() {
5437
5502
  if (typeof window !== "undefined" && window.__STREAM_MONACO_DEBUG__ !== void 0) {
@@ -5528,6 +5593,14 @@ var EditorManager = class {
5528
5593
  }
5529
5594
  maybeScrollToBottom(targetLine) {
5530
5595
  this.rafScheduler.schedule("maybe-scroll", () => {
5596
+ if (!(this.autoScrollOnUpdate && this.shouldAutoScroll)) {
5597
+ this.dlog("maybeScrollToBottom skipped (auto-scroll disabled)", {
5598
+ autoScrollOnUpdate: this.autoScrollOnUpdate,
5599
+ shouldAutoScroll: this.shouldAutoScroll,
5600
+ targetLine
5601
+ });
5602
+ return;
5603
+ }
5531
5604
  const hasVS = this.hasVerticalScrollbar();
5532
5605
  this.dlog("maybeScrollToBottom called", {
5533
5606
  autoScrollOnUpdate: this.autoScrollOnUpdate,
@@ -5535,8 +5608,8 @@ var EditorManager = class {
5535
5608
  hasVerticalScrollbar: hasVS,
5536
5609
  targetLine
5537
5610
  });
5538
- if (!(this.autoScrollOnUpdate && this.shouldAutoScroll && this.hasVerticalScrollbar())) {
5539
- this.dlog("maybeScrollToBottom skipped (auto-scroll conditions not met)");
5611
+ if (!hasVS) {
5612
+ this.dlog("maybeScrollToBottom skipped (no vertical scrollbar)");
5540
5613
  return;
5541
5614
  }
5542
5615
  const model = this.editorView.getModel();
@@ -5796,7 +5869,7 @@ var EditorManager = class {
5796
5869
  this.lastScrollTop = v;
5797
5870
  }
5798
5871
  });
5799
- this.maybeScrollToBottom();
5872
+ if (this.shouldAutoScroll) this.maybeScrollToBottom();
5800
5873
  return this.editorView;
5801
5874
  }
5802
5875
  syncLastKnownCode() {
@@ -5967,10 +6040,31 @@ var EditorManager = class {
5967
6040
  this.appendBuffer.push(appendText);
5968
6041
  if (!this.appendBufferScheduled) {
5969
6042
  this.appendBufferScheduled = true;
5970
- this.rafScheduler.schedule("append", () => this.flushAppendBuffer());
6043
+ this.scheduleFlushAppendBuffer();
5971
6044
  }
5972
6045
  }
5973
6046
  }
6047
+ scheduleFlushAppendBuffer() {
6048
+ const schedule = () => {
6049
+ this.rafScheduler.schedule("append", () => this.flushAppendBuffer());
6050
+ };
6051
+ if (!this.updateThrottleMs) {
6052
+ schedule();
6053
+ return;
6054
+ }
6055
+ const now = Date.now();
6056
+ const since = now - this.lastAppendFlushTime;
6057
+ if (since >= this.updateThrottleMs) {
6058
+ schedule();
6059
+ return;
6060
+ }
6061
+ if (this.appendFlushThrottleTimer != null) return;
6062
+ const wait = this.updateThrottleMs - since;
6063
+ this.appendFlushThrottleTimer = setTimeout(() => {
6064
+ this.appendFlushThrottleTimer = null;
6065
+ schedule();
6066
+ }, wait);
6067
+ }
5974
6068
  applyMinimalEdit(prev, next) {
5975
6069
  if (!this.editorView) return;
5976
6070
  const model = this.editorView.getModel();
@@ -6011,6 +6105,7 @@ var EditorManager = class {
6011
6105
  if (!this.editorView) return;
6012
6106
  if (this.appendBuffer.length === 0) return;
6013
6107
  this.appendBufferScheduled = false;
6108
+ this.lastAppendFlushTime = Date.now();
6014
6109
  const model = this.editorView.getModel();
6015
6110
  if (!model) {
6016
6111
  this.appendBuffer.length = 0;
@@ -6065,6 +6160,11 @@ var EditorManager = class {
6065
6160
  this.updateThrottleTimer = null;
6066
6161
  this.rafScheduler.schedule("update", () => this.flushPendingUpdate());
6067
6162
  }
6163
+ if (!this.updateThrottleMs && this.appendFlushThrottleTimer != null) {
6164
+ clearTimeout(this.appendFlushThrottleTimer);
6165
+ this.appendFlushThrottleTimer = null;
6166
+ this.rafScheduler.schedule("append", () => this.flushAppendBuffer());
6167
+ }
6068
6168
  }
6069
6169
  getUpdateThrottleMs() {
6070
6170
  return this.updateThrottleMs;
@@ -6141,6 +6241,8 @@ function arraysEqual(a, b) {
6141
6241
  const LEGACY_ONIG_INIT_KEY = "__streamMonacoLegacyOnigurumaInit__";
6142
6242
  const LEGACY_ENGINE_KEY = "__streamMonacoLegacyShikiEngine__";
6143
6243
  const LEGACY_MONACO_LANGS_INIT_KEY = "__streamMonacoLegacyMonacoLangsInit__";
6244
+ const PERF_HOOKS_ENABLED_KEY = "__STREAM_MONACO_ENABLE_INTERNAL_PERF_HOOKS__";
6245
+ let instrumentedHighlighterCache = /* @__PURE__ */ new WeakMap();
6144
6246
  async function awaitLegacyOnigurumaInitIfPresent() {
6145
6247
  try {
6146
6248
  var _globalThis;
@@ -6191,9 +6293,109 @@ let lastPatchedHighlighter = null;
6191
6293
  let lastPatchedLanguages = /* @__PURE__ */ new Set();
6192
6294
  const monacoThemeByKey = /* @__PURE__ */ new Map();
6193
6295
  const monacoLanguageSet = /* @__PURE__ */ new Set();
6296
+ function nowMs() {
6297
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
6298
+ }
6299
+ function isPerfHooksEnabled() {
6300
+ try {
6301
+ var _globalThis4;
6302
+ return typeof globalThis !== "undefined" && ((_globalThis4 = globalThis) === null || _globalThis4 === void 0 ? void 0 : _globalThis4[PERF_HOOKS_ENABLED_KEY]) === true;
6303
+ } catch {
6304
+ return false;
6305
+ }
6306
+ }
6307
+ function getPerfHook(name) {
6308
+ if (!isPerfHooksEnabled()) return null;
6309
+ try {
6310
+ var _STREAM_MONACO_PERF__;
6311
+ if (typeof globalThis === "undefined") return null;
6312
+ const hook = (_STREAM_MONACO_PERF__ = globalThis.__STREAM_MONACO_PERF__) === null || _STREAM_MONACO_PERF__ === void 0 ? void 0 : _STREAM_MONACO_PERF__[name];
6313
+ return typeof hook === "function" ? hook : null;
6314
+ } catch {
6315
+ return null;
6316
+ }
6317
+ }
6318
+ function getTokenizationPerfHook() {
6319
+ return getPerfHook("recordTokenize");
6320
+ }
6321
+ function getGrammarTokenizationPerfHook() {
6322
+ return getPerfHook("recordGrammarTokenize");
6323
+ }
6324
+ function getThemeRegistrationPerfHook() {
6325
+ return getPerfHook("recordThemeRegistration");
6326
+ }
6327
+ function recordTokenize(hook, language, durationMs, line, tokenCount, failed) {
6328
+ if (!hook) return;
6329
+ try {
6330
+ hook({
6331
+ language,
6332
+ durationMs,
6333
+ lineLength: line.length,
6334
+ lineSample: line.slice(0, 120),
6335
+ tokenCount,
6336
+ failed
6337
+ });
6338
+ } catch {}
6339
+ }
6340
+ function recordGrammarTokenize(language, durationMs, line, stoppedEarly, tokenCount) {
6341
+ const hook = getGrammarTokenizationPerfHook();
6342
+ if (!hook) return;
6343
+ try {
6344
+ hook({
6345
+ language,
6346
+ durationMs,
6347
+ lineLength: line.length,
6348
+ lineSample: line.slice(0, 120),
6349
+ stoppedEarly,
6350
+ tokenCount
6351
+ });
6352
+ } catch {}
6353
+ }
6354
+ function recordThemeRegistration(event) {
6355
+ const hook = getThemeRegistrationPerfHook();
6356
+ if (!hook) return;
6357
+ try {
6358
+ hook(event);
6359
+ } catch {}
6360
+ }
6361
+ function getProxyMember(target, prop) {
6362
+ const value = Reflect.get(target, prop, target);
6363
+ return typeof value === "function" ? value.bind(target) : value;
6364
+ }
6194
6365
  function themeKey(t) {
6195
6366
  return typeof t === "string" ? t : t.name ?? JSON.stringify(t);
6196
6367
  }
6368
+ function maybeInstrumentHighlighterGrammar(highlighter) {
6369
+ if (!getGrammarTokenizationPerfHook()) return highlighter;
6370
+ if (!highlighter || typeof highlighter !== "object" && typeof highlighter !== "function") return highlighter;
6371
+ const cached = instrumentedHighlighterCache.get(highlighter);
6372
+ if (cached) return cached;
6373
+ const grammarProxyCache = /* @__PURE__ */ new WeakMap();
6374
+ const instrumentedHighlighter = new Proxy(highlighter, { get(target, prop, _receiver) {
6375
+ if (prop !== "getLanguage") return getProxyMember(target, prop);
6376
+ return (language) => {
6377
+ const grammar = target.getLanguage(language);
6378
+ if (!grammar || typeof grammar !== "object" || typeof grammar.tokenizeLine2 !== "function") return grammar;
6379
+ const cachedGrammar = grammarProxyCache.get(grammar);
6380
+ if (cachedGrammar) return cachedGrammar;
6381
+ const instrumentedGrammar = new Proxy(grammar, { get(grammarTarget, grammarProp, _grammarReceiver) {
6382
+ if (grammarProp !== "tokenizeLine2") return getProxyMember(grammarTarget, grammarProp);
6383
+ const originalTokenizeLine2 = grammarTarget.tokenizeLine2.bind(grammarTarget);
6384
+ return (line, ruleStack, timeLimit) => {
6385
+ var _result$tokens;
6386
+ const startedAt = nowMs();
6387
+ const result = originalTokenizeLine2(line, ruleStack, timeLimit);
6388
+ recordGrammarTokenize(language, nowMs() - startedAt, line, !!(result === null || result === void 0 ? void 0 : result.stoppedEarly), typeof (result === null || result === void 0 || (_result$tokens = result.tokens) === null || _result$tokens === void 0 ? void 0 : _result$tokens.length) === "number" ? result.tokens.length / 2 : 0);
6389
+ return result;
6390
+ };
6391
+ } });
6392
+ grammarProxyCache.set(grammar, instrumentedGrammar);
6393
+ return instrumentedGrammar;
6394
+ };
6395
+ } });
6396
+ instrumentedHighlighterCache.set(highlighter, instrumentedHighlighter);
6397
+ return instrumentedHighlighter;
6398
+ }
6197
6399
  async function ensureMonacoHighlighter(themes, languages$1) {
6198
6400
  for (const t of themes) monacoThemeByKey.set(themeKey(t), t);
6199
6401
  for (const l of languages$1) monacoLanguageSet.add(l);
@@ -6203,7 +6405,11 @@ async function ensureMonacoHighlighter(themes, languages$1) {
6203
6405
  monacoHighlighterPromise = createHighlighterWithLegacyEngineIfNeeded({
6204
6406
  themes: initialThemes,
6205
6407
  langs: initialLangs
6206
- }).then((h$1) => h$1);
6408
+ }).then((h$1) => {
6409
+ h$1.__streamMonacoLoadedThemes = new Set(initialThemes.map((t) => themeKey(t)));
6410
+ h$1.__streamMonacoLoadedLangs = new Set(initialLangs);
6411
+ return h$1;
6412
+ });
6207
6413
  }
6208
6414
  const h = await monacoHighlighterPromise;
6209
6415
  const wantsThemes = Array.from(monacoThemeByKey.values());
@@ -6231,7 +6437,11 @@ async function ensureMonacoHighlighter(themes, languages$1) {
6231
6437
  const p = createHighlighterWithLegacyEngineIfNeeded({
6232
6438
  themes: wantsThemes,
6233
6439
  langs: wantsLangs
6234
- }).then((hh) => hh);
6440
+ }).then((hh) => {
6441
+ hh.__streamMonacoLoadedThemes = new Set(wantsThemes.map((t) => themeKey(t)));
6442
+ hh.__streamMonacoLoadedLangs = new Set(wantsLangs);
6443
+ return hh;
6444
+ });
6235
6445
  monacoHighlighterPromise = p;
6236
6446
  return p;
6237
6447
  }
@@ -6250,6 +6460,7 @@ function clearHighlighterCache() {
6250
6460
  monacoThemeByKey.clear();
6251
6461
  monacoLanguageSet.clear();
6252
6462
  themeRegisterPromise = null;
6463
+ instrumentedHighlighterCache = /* @__PURE__ */ new WeakMap();
6253
6464
  languagesRegistered = false;
6254
6465
  currentLanguages = [];
6255
6466
  }
@@ -6316,9 +6527,15 @@ async function getOrCreateHighlighter(themes, languages$1) {
6316
6527
  */
6317
6528
  async function registerMonacoThemes(themes, languages$1) {
6318
6529
  return enqueueRegistration(async () => {
6530
+ const registrationStartedAt = nowMs();
6531
+ let ensureHighlighterMs = 0;
6532
+ let patchMonacoMs = 0;
6533
+ let patchedMonaco = false;
6319
6534
  registerMonacoLanguages(languages$1);
6320
6535
  const p = (async () => {
6536
+ const ensureHighlighterStartedAt = nowMs();
6321
6537
  const highlighter = await ensureMonacoHighlighter(themes, languages$1);
6538
+ ensureHighlighterMs = nowMs() - ensureHighlighterStartedAt;
6322
6539
  const wantsLangs = Array.from(monacoLanguageSet.values());
6323
6540
  const needsLanguagePatch = lastPatchedHighlighter !== highlighter || wantsLangs.some((l) => !lastPatchedLanguages.has(l));
6324
6541
  if (needsLanguagePatch) {
@@ -6339,9 +6556,17 @@ async function registerMonacoThemes(themes, languages$1) {
6339
6556
  provider = {
6340
6557
  ...provider,
6341
6558
  tokenize(line, state) {
6559
+ const hook = getTokenizationPerfHook();
6560
+ const startedAt = hook ? nowMs() : 0;
6561
+ let tokenCount = 0;
6562
+ let failed = false;
6342
6563
  try {
6343
- return originalTokenize(line, state);
6564
+ const result = originalTokenize(line, state);
6565
+ tokenCount = Array.isArray(result === null || result === void 0 ? void 0 : result.tokens) ? result.tokens.length : 0;
6566
+ return result;
6344
6567
  } catch {
6568
+ failed = true;
6569
+ tokenCount = 1;
6345
6570
  return {
6346
6571
  endState: state,
6347
6572
  tokens: [{
@@ -6349,6 +6574,8 @@ async function registerMonacoThemes(themes, languages$1) {
6349
6574
  scopes: ""
6350
6575
  }]
6351
6576
  };
6577
+ } finally {
6578
+ if (hook) recordTokenize(hook, lang, nowMs() - startedAt, line, tokenCount, failed);
6352
6579
  }
6353
6580
  }
6354
6581
  };
@@ -6357,7 +6584,10 @@ async function registerMonacoThemes(themes, languages$1) {
6357
6584
  }
6358
6585
  }
6359
6586
  };
6360
- (0, __shikijs_monaco.shikiToMonaco)(highlighter, monacoProxy);
6587
+ const patchMonacoStartedAt = nowMs();
6588
+ (0, __shikijs_monaco.shikiToMonaco)(maybeInstrumentHighlighterGrammar(highlighter), monacoProxy);
6589
+ patchMonacoMs = nowMs() - patchMonacoStartedAt;
6590
+ patchedMonaco = true;
6361
6591
  lastPatchedHighlighter = highlighter;
6362
6592
  lastPatchedLanguages = new Set(wantsLangs);
6363
6593
  }
@@ -6367,6 +6597,14 @@ async function registerMonacoThemes(themes, languages$1) {
6367
6597
  setThemeRegisterPromise(p);
6368
6598
  try {
6369
6599
  const res = await p;
6600
+ recordThemeRegistration({
6601
+ durationMs: nowMs() - registrationStartedAt,
6602
+ ensureHighlighterMs,
6603
+ patchMonacoMs,
6604
+ themes: themes.length,
6605
+ languages: languages$1.length,
6606
+ patchedMonaco
6607
+ });
6370
6608
  return res;
6371
6609
  } catch (e) {
6372
6610
  setThemeRegisterPromise(null);
@@ -6500,7 +6738,8 @@ function useMonaco(monacoOptions = {}) {
6500
6738
  let modifiedModel = null;
6501
6739
  const themes = monacoOptions.themes && ((_monacoOptions$themes = monacoOptions.themes) === null || _monacoOptions$themes === void 0 ? void 0 : _monacoOptions$themes.length) ? monacoOptions.themes : defaultThemes;
6502
6740
  if (!Array.isArray(themes) || themes.length < 2) throw new Error("Monaco themes must be an array with at least two themes: [darkTheme, lightTheme]");
6503
- const languages$1 = monacoOptions.languages ?? defaultLanguages;
6741
+ const explicitLanguages = monacoOptions.languages;
6742
+ const languages$1 = explicitLanguages ?? defaultLanguages;
6504
6743
  const MAX_HEIGHT = monacoOptions.MAX_HEIGHT ?? 500;
6505
6744
  const autoScrollOnUpdate = monacoOptions.autoScrollOnUpdate ?? true;
6506
6745
  const autoScrollInitial = monacoOptions.autoScrollInitial ?? true;
@@ -6589,10 +6828,27 @@ function useMonaco(monacoOptions = {}) {
6589
6828
  console.warn("onThemeChange callback threw an error:", err);
6590
6829
  }
6591
6830
  }
6592
- async function ensureThemeRegistered(themeName) {
6831
+ function normalizeLanguage(language) {
6832
+ if (!language) return null;
6833
+ return processedLanguage(language) || language;
6834
+ }
6835
+ function resolveCreateLanguages(primaryLanguage) {
6836
+ const primary = normalizeLanguage(primaryLanguage);
6837
+ if (Array.isArray(explicitLanguages) && explicitLanguages.length) {
6838
+ const set = /* @__PURE__ */ new Set();
6839
+ for (const language of explicitLanguages) {
6840
+ const normalized = normalizeLanguage(language);
6841
+ if (normalized) set.add(normalized);
6842
+ }
6843
+ if (primary) set.add(primary);
6844
+ return Array.from(set);
6845
+ }
6846
+ return primary ? [primary] : ["typescript"];
6847
+ }
6848
+ async function ensureThemeRegistered(themeName, requestedLanguages = languages$1) {
6593
6849
  const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
6594
6850
  const list = availableNames.includes(themeName) ? themes : themes.concat(themeName);
6595
- await registerMonacoThemes(list, languages$1);
6851
+ await registerMonacoThemes(list, requestedLanguages);
6596
6852
  }
6597
6853
  function resolveRequestedThemeName() {
6598
6854
  return requestedThemeName ?? globalRequestedThemeName ?? monacoOptions.theme ?? currentTheme.value;
@@ -6669,11 +6925,12 @@ function useMonaco(monacoOptions = {}) {
6669
6925
  queuedEditorUpdateDuringCreate = null;
6670
6926
  disposeAllPendingCreateDisposables();
6671
6927
  }
6672
- async function resolveCreateThemeName(requestId, kind) {
6928
+ async function resolveCreateThemeName(requestId, kind, primaryLanguage) {
6673
6929
  let themeName = resolveRequestedThemeName();
6930
+ const createLanguages = resolveCreateLanguages(primaryLanguage);
6674
6931
  while (true) {
6675
6932
  assertCreateStillActive(requestId, kind);
6676
- await ensureThemeRegistered(themeName);
6933
+ await ensureThemeRegistered(themeName, createLanguages);
6677
6934
  assertCreateStillActive(requestId, kind);
6678
6935
  const latestThemeName = resolveRequestedThemeName();
6679
6936
  if (latestThemeName === themeName) return themeName;
@@ -6692,7 +6949,7 @@ function useMonaco(monacoOptions = {}) {
6692
6949
  if (requestDisposables.length) pendingCreateDisposables.set(requestId, requestDisposables);
6693
6950
  let nextEditorMgr = null;
6694
6951
  try {
6695
- const initialThemeName = await resolveCreateThemeName(requestId, "editor");
6952
+ const initialThemeName = await resolveCreateThemeName(requestId, "editor", language);
6696
6953
  nextEditorMgr = new EditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, monacoOptions.revealDebounceMs, monacoOptions.updateThrottleMs);
6697
6954
  const nextEditorView = await nextEditorMgr.createEditor(container, code, language, initialThemeName);
6698
6955
  assertCreateStillActive(requestId, "editor");
@@ -6739,7 +6996,7 @@ function useMonaco(monacoOptions = {}) {
6739
6996
  if (requestDisposables.length) pendingCreateDisposables.set(requestId, requestDisposables);
6740
6997
  let nextDiffMgr = null;
6741
6998
  try {
6742
- const initialThemeName = await resolveCreateThemeName(requestId, "diff");
6999
+ const initialThemeName = await resolveCreateThemeName(requestId, "diff", language);
6743
7000
  nextDiffMgr = new DiffEditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, diffAutoScroll, monacoOptions.revealDebounceMs, monacoOptions.diffUpdateThrottleMs);
6744
7001
  const nextDiffEditorView = await nextDiffMgr.createDiffEditor(container, originalCode, modifiedCode, language, initialThemeName);
6745
7002
  assertCreateStillActive(requestId, "diff");