stream-monaco 0.0.42 → 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.
@@ -522,6 +522,14 @@ function createScrollWatcherForEditor(ed, opts) {
522
522
  return api;
523
523
  }
524
524
 
525
+ //#endregion
526
+ //#region src/utils/textChunks.ts
527
+ function countLineBreaks(text) {
528
+ let count = 0;
529
+ for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) count += 1;
530
+ return count;
531
+ }
532
+
525
533
  //#endregion
526
534
  //#region src/core/diffAppearance.ts
527
535
  function parseCssColorRgb(color) {
@@ -4426,9 +4434,10 @@ var DiffEditorManager = class DiffEditorManager {
4426
4434
  shouldAutoScrollDiff: this.shouldAutoScrollDiff
4427
4435
  });
4428
4436
  if (!this.diffEditorView) return;
4437
+ if (!(this.diffAutoScroll && this.autoScrollOnUpdate && this.shouldAutoScrollDiff)) return;
4429
4438
  const hasV = this.hasVerticalScrollbarModified();
4430
4439
  log("diff", "hasVerticalScrollbarModified ->", hasV);
4431
- if (!(this.diffAutoScroll && this.autoScrollOnUpdate && this.shouldAutoScrollDiff && hasV)) return;
4440
+ if (!hasV) return;
4432
4441
  const me = this.diffEditorView.getModifiedEditor();
4433
4442
  const model = me.getModel();
4434
4443
  const currentLine = (model === null || model === void 0 ? void 0 : model.getLineCount()) ?? 1;
@@ -4650,7 +4659,7 @@ var DiffEditorManager = class DiffEditorManager {
4650
4659
  this.diffComputedVersions = null;
4651
4660
  this.diffPresentationDisposables.push(this.diffEditorView.onDidUpdateDiff(() => {
4652
4661
  this.diffComputedVersions = this.captureCurrentDiffVersions();
4653
- this.syncDiffEditorLayoutToContainer();
4662
+ this.scheduleSyncDiffEditorLayoutToContainer();
4654
4663
  this.scheduleSyncDiffPresentationDecorations();
4655
4664
  }));
4656
4665
  this.diffPresentationDisposables.push(oEditor.onDidChangeModelContent(() => {
@@ -4815,6 +4824,7 @@ var DiffEditorManager = class DiffEditorManager {
4815
4824
  }
4816
4825
  updateModified(newCode, codeLanguage) {
4817
4826
  if (!this.diffEditorView || !this.modifiedModel) return;
4827
+ this.syncLastKnownModified();
4818
4828
  if (codeLanguage) {
4819
4829
  const lang = processedLanguage(codeLanguage);
4820
4830
  if (lang && this.modifiedModel.getLanguageId() !== lang) monaco_shim_exports.editor.setModelLanguage(this.modifiedModel, lang);
@@ -4827,7 +4837,7 @@ var DiffEditorManager = class DiffEditorManager {
4827
4837
  if (tailAppend) this.appendModified(newCode.slice(prev.length), codeLanguage);
4828
4838
  else {
4829
4839
  this.flushModifiedAppendBufferSync();
4830
- const prevAfterFlush = this.modifiedModel.getValue();
4840
+ const prevAfterFlush = this.lastKnownModifiedCode ?? this.modifiedModel.getValue();
4831
4841
  const prevLine = this.modifiedModel.getLineCount();
4832
4842
  this.applyMinimalEditToModel(this.modifiedModel, prevAfterFlush, newCode);
4833
4843
  const newLine = this.modifiedModel.getLineCount();
@@ -5077,6 +5087,7 @@ var DiffEditorManager = class DiffEditorManager {
5077
5087
  }
5078
5088
  const { original, modified, lang } = this.pendingDiffUpdate;
5079
5089
  this.pendingDiffUpdate = null;
5090
+ this.syncLastKnownModified();
5080
5091
  this.flushOriginalAppendBufferSync();
5081
5092
  this.flushModifiedAppendBufferSync();
5082
5093
  if (lang) {
@@ -5097,7 +5108,7 @@ var DiffEditorManager = class DiffEditorManager {
5097
5108
  else this.applyMinimalEditToModel(o, prevO, original);
5098
5109
  this.lastKnownOriginalCode = original;
5099
5110
  }
5100
- const prevM = m.getValue();
5111
+ const prevM = this.lastKnownModifiedCode;
5101
5112
  const prevMLineCount = m.getLineCount();
5102
5113
  const modifiedTailAppend = prevM !== modified && modified.startsWith(prevM) && prevM.length < modified.length;
5103
5114
  const hasContentChange = prevO !== original || prevM !== modified;
@@ -5138,6 +5149,33 @@ var DiffEditorManager = class DiffEditorManager {
5138
5149
  this.preserveNativeDiffDecorationsOnStaleAppend = true;
5139
5150
  this.appendToModel(this.modifiedModel, text);
5140
5151
  }
5152
+ splitAppendTextForProgressiveFlush(text, maxChunkChars = 12e3, maxChunkLines = 200) {
5153
+ if (!text || text.length <= maxChunkChars) return [text];
5154
+ const chunks = [];
5155
+ let start = 0;
5156
+ let lineCount = 0;
5157
+ let lastSafeEnd = 0;
5158
+ for (let i = 0; i < text.length; i++) {
5159
+ if (text.charCodeAt(i) === 10) {
5160
+ lineCount += 1;
5161
+ lastSafeEnd = i + 1;
5162
+ }
5163
+ if (i - start + 1 < maxChunkChars && lineCount < maxChunkLines) continue;
5164
+ let end = lastSafeEnd > start ? lastSafeEnd : i + 1;
5165
+ if (end < text.length) {
5166
+ const prev = text.charCodeAt(end - 1);
5167
+ const next = text.charCodeAt(end);
5168
+ if (prev >= 55296 && prev <= 56319 && next >= 56320 && next <= 57343) end += 1;
5169
+ }
5170
+ chunks.push(text.slice(start, end));
5171
+ start = end;
5172
+ i = end - 1;
5173
+ lineCount = 0;
5174
+ lastSafeEnd = start;
5175
+ }
5176
+ if (start < text.length) chunks.push(text.slice(start));
5177
+ return chunks.length ? chunks : [text];
5178
+ }
5141
5179
  async flushAppendBufferDiff() {
5142
5180
  if (!this.diffEditorView) return;
5143
5181
  if (this.appendBufferOriginalDiff.length === 0 && this.appendBufferModifiedDiff.length === 0) return;
@@ -5158,17 +5196,16 @@ var DiffEditorManager = class DiffEditorManager {
5158
5196
  return;
5159
5197
  }
5160
5198
  let parts = this.appendBufferModifiedDiff.splice(0);
5199
+ if (parts.length === 0) {
5200
+ this.eagerlyGrowDiffContainerHeight();
5201
+ return;
5202
+ }
5161
5203
  const prevLineInit = model.getLineCount();
5162
5204
  const totalText = parts.join("");
5163
5205
  const totalChars = totalText.length;
5164
- if (parts.length === 1 && totalChars > 5e3) {
5165
- const lines = totalText.split(/\r?\n/);
5166
- const chunkSize = 200;
5167
- const chunks = [];
5168
- for (let i = 0; i < lines.length; i += chunkSize) chunks.push(`${lines.slice(i, i + chunkSize).join("\n")}\n`);
5169
- if (chunks.length > 1) parts = chunks;
5170
- }
5171
- const applyChunked = parts.length > 1 && (totalChars > 2e3 || model.getLineCount && model.getLineCount() + 0 - prevLineInit > 50);
5206
+ const totalLineBreaks = countLineBreaks(totalText);
5207
+ if (parts.length === 1 && totalChars > 5e3) parts = this.splitAppendTextForProgressiveFlush(totalText);
5208
+ const applyChunked = parts.length > 1 && (totalChars > 2e3 || totalLineBreaks > 50);
5172
5209
  log("diff", "flushAppendBufferDiff start", {
5173
5210
  partsCount: parts.length,
5174
5211
  totalChars,
@@ -5187,6 +5224,8 @@ var DiffEditorManager = class DiffEditorManager {
5187
5224
  } catch {}
5188
5225
  if (applyChunked) {
5189
5226
  log("diff", "flushAppendBufferDiff applying chunked", { partsLen: parts.length });
5227
+ if (this.lastKnownModifiedCode == null) this.lastKnownModifiedCode = model.getValue();
5228
+ let currentLength = this.lastKnownModifiedCode.length;
5190
5229
  let idx = 0;
5191
5230
  for (const part of parts) {
5192
5231
  if (!part) continue;
@@ -5196,17 +5235,9 @@ var DiffEditorManager = class DiffEditorManager {
5196
5235
  partLen: part.length,
5197
5236
  prevLine
5198
5237
  });
5199
- const lastColumn$1 = model.getLineMaxColumn(prevLine);
5200
- const range$1 = new monaco_shim_exports.Range(prevLine, lastColumn$1, prevLine, lastColumn$1);
5201
5238
  this.preserveNativeDiffDecorationsOnStaleAppend = true;
5202
- this.runAsProgrammaticModifiedContentChange(() => {
5203
- model.applyEdits([{
5204
- range: range$1,
5205
- text: part,
5206
- forceMoveMarkers: true
5207
- }]);
5208
- });
5209
- this.lastKnownModifiedCode = model.getValue();
5239
+ this.appendToModel(model, part, currentLength);
5240
+ currentLength += part.length;
5210
5241
  const newLine$1 = model.getLineCount();
5211
5242
  this.lastKnownModifiedLineCount = newLine$1;
5212
5243
  await new Promise((resolve) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(resolve) : setTimeout(resolve, 0));
@@ -5232,23 +5263,15 @@ var DiffEditorManager = class DiffEditorManager {
5232
5263
  newLine: newLine$1
5233
5264
  });
5234
5265
  }
5266
+ this.lastKnownModifiedCode = model.getValue();
5235
5267
  if (suppressedByFlush) watcherApi.setSuppressed(false);
5236
5268
  return;
5237
5269
  }
5238
5270
  const text = totalText;
5239
5271
  this.appendBufferModifiedDiff.length = 0;
5240
5272
  prevLine = model.getLineCount();
5241
- const lastColumn = model.getLineMaxColumn(prevLine);
5242
- const range = new monaco_shim_exports.Range(prevLine, lastColumn, prevLine, lastColumn);
5243
5273
  this.preserveNativeDiffDecorationsOnStaleAppend = true;
5244
- this.runAsProgrammaticModifiedContentChange(() => {
5245
- model.applyEdits([{
5246
- range,
5247
- text,
5248
- forceMoveMarkers: true
5249
- }]);
5250
- });
5251
- this.lastKnownModifiedCode = model.getValue();
5274
+ this.appendToModel(model, text);
5252
5275
  const newLine = model.getLineCount();
5253
5276
  this.lastKnownModifiedLineCount = newLine;
5254
5277
  this.eagerlyGrowDiffContainerHeight();
@@ -5291,8 +5314,30 @@ var DiffEditorManager = class DiffEditorManager {
5291
5314
  });
5292
5315
  if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
5293
5316
  }
5294
- appendToModel(model, appendText) {
5317
+ getModelValueLength(model) {
5318
+ const getValueLength = model.getValueLength;
5319
+ if (typeof getValueLength === "function") try {
5320
+ return getValueLength.call(model);
5321
+ } catch {}
5322
+ return model.getValue().length;
5323
+ }
5324
+ mergeKnownAppend(known, appendText, previousLength, model) {
5325
+ if (known == null) return model.getValue();
5326
+ const nextLength = previousLength + appendText.length;
5327
+ if (known.length === previousLength) return known + appendText;
5328
+ if (known.length >= nextLength && known.slice(previousLength, nextLength) === appendText) return known;
5329
+ return model.getValue();
5330
+ }
5331
+ syncKnownCodeAfterAppend(model, appendText, previousLength) {
5332
+ if (model === this.originalModel) {
5333
+ this.lastKnownOriginalCode = this.mergeKnownAppend(this.lastKnownOriginalCode, appendText, previousLength, model);
5334
+ return;
5335
+ }
5336
+ if (model === this.modifiedModel) this.lastKnownModifiedCode = this.mergeKnownAppend(this.lastKnownModifiedCode, appendText, previousLength, model);
5337
+ }
5338
+ appendToModel(model, appendText, knownLength) {
5295
5339
  if (!appendText) return;
5340
+ const previousLength = knownLength != null ? knownLength : this.getModelValueLength(model);
5296
5341
  const lastLine = model.getLineCount();
5297
5342
  const lastColumn = model.getLineMaxColumn(lastLine);
5298
5343
  const range = new monaco_shim_exports.Range(lastLine, lastColumn, lastLine, lastColumn);
@@ -5304,6 +5349,7 @@ var DiffEditorManager = class DiffEditorManager {
5304
5349
  }]);
5305
5350
  });
5306
5351
  if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
5352
+ this.syncKnownCodeAfterAppend(model, appendText, previousLength);
5307
5353
  }
5308
5354
  applyModelEdit(model, fn) {
5309
5355
  if (model === this.modifiedModel) {
@@ -5341,6 +5387,8 @@ var EditorManager = class {
5341
5387
  minimalEditMaxChangeRatioValue = minimalEditMaxChangeRatio;
5342
5388
  lastUpdateFlushTime = 0;
5343
5389
  updateThrottleTimer = null;
5390
+ lastAppendFlushTime = 0;
5391
+ appendFlushThrottleTimer = null;
5344
5392
  shouldAutoScroll = true;
5345
5393
  scrollWatcher = null;
5346
5394
  scrollWatcherSuppressionTimer = null;
@@ -5440,6 +5488,10 @@ var EditorManager = class {
5440
5488
  clearTimeout(this.updateThrottleTimer);
5441
5489
  this.updateThrottleTimer = null;
5442
5490
  }
5491
+ if (this.appendFlushThrottleTimer != null) {
5492
+ clearTimeout(this.appendFlushThrottleTimer);
5493
+ this.appendFlushThrottleTimer = null;
5494
+ }
5443
5495
  }
5444
5496
  initDebugFlag() {
5445
5497
  if (typeof window !== "undefined" && window.__STREAM_MONACO_DEBUG__ !== void 0) {
@@ -5536,6 +5588,14 @@ var EditorManager = class {
5536
5588
  }
5537
5589
  maybeScrollToBottom(targetLine) {
5538
5590
  this.rafScheduler.schedule("maybe-scroll", () => {
5591
+ if (!(this.autoScrollOnUpdate && this.shouldAutoScroll)) {
5592
+ this.dlog("maybeScrollToBottom skipped (auto-scroll disabled)", {
5593
+ autoScrollOnUpdate: this.autoScrollOnUpdate,
5594
+ shouldAutoScroll: this.shouldAutoScroll,
5595
+ targetLine
5596
+ });
5597
+ return;
5598
+ }
5539
5599
  const hasVS = this.hasVerticalScrollbar();
5540
5600
  this.dlog("maybeScrollToBottom called", {
5541
5601
  autoScrollOnUpdate: this.autoScrollOnUpdate,
@@ -5543,8 +5603,8 @@ var EditorManager = class {
5543
5603
  hasVerticalScrollbar: hasVS,
5544
5604
  targetLine
5545
5605
  });
5546
- if (!(this.autoScrollOnUpdate && this.shouldAutoScroll && this.hasVerticalScrollbar())) {
5547
- this.dlog("maybeScrollToBottom skipped (auto-scroll conditions not met)");
5606
+ if (!hasVS) {
5607
+ this.dlog("maybeScrollToBottom skipped (no vertical scrollbar)");
5548
5608
  return;
5549
5609
  }
5550
5610
  const model = this.editorView.getModel();
@@ -5804,7 +5864,7 @@ var EditorManager = class {
5804
5864
  this.lastScrollTop = v;
5805
5865
  }
5806
5866
  });
5807
- this.maybeScrollToBottom();
5867
+ if (this.shouldAutoScroll) this.maybeScrollToBottom();
5808
5868
  return this.editorView;
5809
5869
  }
5810
5870
  syncLastKnownCode() {
@@ -5975,10 +6035,31 @@ var EditorManager = class {
5975
6035
  this.appendBuffer.push(appendText);
5976
6036
  if (!this.appendBufferScheduled) {
5977
6037
  this.appendBufferScheduled = true;
5978
- this.rafScheduler.schedule("append", () => this.flushAppendBuffer());
6038
+ this.scheduleFlushAppendBuffer();
5979
6039
  }
5980
6040
  }
5981
6041
  }
6042
+ scheduleFlushAppendBuffer() {
6043
+ const schedule = () => {
6044
+ this.rafScheduler.schedule("append", () => this.flushAppendBuffer());
6045
+ };
6046
+ if (!this.updateThrottleMs) {
6047
+ schedule();
6048
+ return;
6049
+ }
6050
+ const now = Date.now();
6051
+ const since = now - this.lastAppendFlushTime;
6052
+ if (since >= this.updateThrottleMs) {
6053
+ schedule();
6054
+ return;
6055
+ }
6056
+ if (this.appendFlushThrottleTimer != null) return;
6057
+ const wait = this.updateThrottleMs - since;
6058
+ this.appendFlushThrottleTimer = setTimeout(() => {
6059
+ this.appendFlushThrottleTimer = null;
6060
+ schedule();
6061
+ }, wait);
6062
+ }
5982
6063
  applyMinimalEdit(prev, next) {
5983
6064
  if (!this.editorView) return;
5984
6065
  const model = this.editorView.getModel();
@@ -6019,6 +6100,7 @@ var EditorManager = class {
6019
6100
  if (!this.editorView) return;
6020
6101
  if (this.appendBuffer.length === 0) return;
6021
6102
  this.appendBufferScheduled = false;
6103
+ this.lastAppendFlushTime = Date.now();
6022
6104
  const model = this.editorView.getModel();
6023
6105
  if (!model) {
6024
6106
  this.appendBuffer.length = 0;
@@ -6073,6 +6155,11 @@ var EditorManager = class {
6073
6155
  this.updateThrottleTimer = null;
6074
6156
  this.rafScheduler.schedule("update", () => this.flushPendingUpdate());
6075
6157
  }
6158
+ if (!this.updateThrottleMs && this.appendFlushThrottleTimer != null) {
6159
+ clearTimeout(this.appendFlushThrottleTimer);
6160
+ this.appendFlushThrottleTimer = null;
6161
+ this.rafScheduler.schedule("append", () => this.flushAppendBuffer());
6162
+ }
6076
6163
  }
6077
6164
  getUpdateThrottleMs() {
6078
6165
  return this.updateThrottleMs;
@@ -6149,6 +6236,8 @@ function arraysEqual(a, b) {
6149
6236
  const LEGACY_ONIG_INIT_KEY = "__streamMonacoLegacyOnigurumaInit__";
6150
6237
  const LEGACY_ENGINE_KEY = "__streamMonacoLegacyShikiEngine__";
6151
6238
  const LEGACY_MONACO_LANGS_INIT_KEY = "__streamMonacoLegacyMonacoLangsInit__";
6239
+ const PERF_HOOKS_ENABLED_KEY = "__STREAM_MONACO_ENABLE_INTERNAL_PERF_HOOKS__";
6240
+ let instrumentedHighlighterCache = /* @__PURE__ */ new WeakMap();
6152
6241
  async function awaitLegacyOnigurumaInitIfPresent() {
6153
6242
  try {
6154
6243
  var _globalThis;
@@ -6199,9 +6288,109 @@ let lastPatchedHighlighter = null;
6199
6288
  let lastPatchedLanguages = /* @__PURE__ */ new Set();
6200
6289
  const monacoThemeByKey = /* @__PURE__ */ new Map();
6201
6290
  const monacoLanguageSet = /* @__PURE__ */ new Set();
6291
+ function nowMs() {
6292
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
6293
+ }
6294
+ function isPerfHooksEnabled() {
6295
+ try {
6296
+ var _globalThis4;
6297
+ return typeof globalThis !== "undefined" && ((_globalThis4 = globalThis) === null || _globalThis4 === void 0 ? void 0 : _globalThis4[PERF_HOOKS_ENABLED_KEY]) === true;
6298
+ } catch {
6299
+ return false;
6300
+ }
6301
+ }
6302
+ function getPerfHook(name) {
6303
+ if (!isPerfHooksEnabled()) return null;
6304
+ try {
6305
+ var _STREAM_MONACO_PERF__;
6306
+ if (typeof globalThis === "undefined") return null;
6307
+ const hook = (_STREAM_MONACO_PERF__ = globalThis.__STREAM_MONACO_PERF__) === null || _STREAM_MONACO_PERF__ === void 0 ? void 0 : _STREAM_MONACO_PERF__[name];
6308
+ return typeof hook === "function" ? hook : null;
6309
+ } catch {
6310
+ return null;
6311
+ }
6312
+ }
6313
+ function getTokenizationPerfHook() {
6314
+ return getPerfHook("recordTokenize");
6315
+ }
6316
+ function getGrammarTokenizationPerfHook() {
6317
+ return getPerfHook("recordGrammarTokenize");
6318
+ }
6319
+ function getThemeRegistrationPerfHook() {
6320
+ return getPerfHook("recordThemeRegistration");
6321
+ }
6322
+ function recordTokenize(hook, language, durationMs, line, tokenCount, failed) {
6323
+ if (!hook) return;
6324
+ try {
6325
+ hook({
6326
+ language,
6327
+ durationMs,
6328
+ lineLength: line.length,
6329
+ lineSample: line.slice(0, 120),
6330
+ tokenCount,
6331
+ failed
6332
+ });
6333
+ } catch {}
6334
+ }
6335
+ function recordGrammarTokenize(language, durationMs, line, stoppedEarly, tokenCount) {
6336
+ const hook = getGrammarTokenizationPerfHook();
6337
+ if (!hook) return;
6338
+ try {
6339
+ hook({
6340
+ language,
6341
+ durationMs,
6342
+ lineLength: line.length,
6343
+ lineSample: line.slice(0, 120),
6344
+ stoppedEarly,
6345
+ tokenCount
6346
+ });
6347
+ } catch {}
6348
+ }
6349
+ function recordThemeRegistration(event) {
6350
+ const hook = getThemeRegistrationPerfHook();
6351
+ if (!hook) return;
6352
+ try {
6353
+ hook(event);
6354
+ } catch {}
6355
+ }
6356
+ function getProxyMember(target, prop) {
6357
+ const value = Reflect.get(target, prop, target);
6358
+ return typeof value === "function" ? value.bind(target) : value;
6359
+ }
6202
6360
  function themeKey(t) {
6203
6361
  return typeof t === "string" ? t : t.name ?? JSON.stringify(t);
6204
6362
  }
6363
+ function maybeInstrumentHighlighterGrammar(highlighter) {
6364
+ if (!getGrammarTokenizationPerfHook()) return highlighter;
6365
+ if (!highlighter || typeof highlighter !== "object" && typeof highlighter !== "function") return highlighter;
6366
+ const cached = instrumentedHighlighterCache.get(highlighter);
6367
+ if (cached) return cached;
6368
+ const grammarProxyCache = /* @__PURE__ */ new WeakMap();
6369
+ const instrumentedHighlighter = new Proxy(highlighter, { get(target, prop, _receiver) {
6370
+ if (prop !== "getLanguage") return getProxyMember(target, prop);
6371
+ return (language) => {
6372
+ const grammar = target.getLanguage(language);
6373
+ if (!grammar || typeof grammar !== "object" || typeof grammar.tokenizeLine2 !== "function") return grammar;
6374
+ const cachedGrammar = grammarProxyCache.get(grammar);
6375
+ if (cachedGrammar) return cachedGrammar;
6376
+ const instrumentedGrammar = new Proxy(grammar, { get(grammarTarget, grammarProp, _grammarReceiver) {
6377
+ if (grammarProp !== "tokenizeLine2") return getProxyMember(grammarTarget, grammarProp);
6378
+ const originalTokenizeLine2 = grammarTarget.tokenizeLine2.bind(grammarTarget);
6379
+ return (line, ruleStack, timeLimit) => {
6380
+ var _result$tokens;
6381
+ const startedAt = nowMs();
6382
+ const result = originalTokenizeLine2(line, ruleStack, timeLimit);
6383
+ 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);
6384
+ return result;
6385
+ };
6386
+ } });
6387
+ grammarProxyCache.set(grammar, instrumentedGrammar);
6388
+ return instrumentedGrammar;
6389
+ };
6390
+ } });
6391
+ instrumentedHighlighterCache.set(highlighter, instrumentedHighlighter);
6392
+ return instrumentedHighlighter;
6393
+ }
6205
6394
  async function ensureMonacoHighlighter(themes, languages$1) {
6206
6395
  for (const t of themes) monacoThemeByKey.set(themeKey(t), t);
6207
6396
  for (const l of languages$1) monacoLanguageSet.add(l);
@@ -6211,7 +6400,11 @@ async function ensureMonacoHighlighter(themes, languages$1) {
6211
6400
  monacoHighlighterPromise = createHighlighterWithLegacyEngineIfNeeded({
6212
6401
  themes: initialThemes,
6213
6402
  langs: initialLangs
6214
- }).then((h$1) => h$1);
6403
+ }).then((h$1) => {
6404
+ h$1.__streamMonacoLoadedThemes = new Set(initialThemes.map((t) => themeKey(t)));
6405
+ h$1.__streamMonacoLoadedLangs = new Set(initialLangs);
6406
+ return h$1;
6407
+ });
6215
6408
  }
6216
6409
  const h = await monacoHighlighterPromise;
6217
6410
  const wantsThemes = Array.from(monacoThemeByKey.values());
@@ -6239,7 +6432,11 @@ async function ensureMonacoHighlighter(themes, languages$1) {
6239
6432
  const p = createHighlighterWithLegacyEngineIfNeeded({
6240
6433
  themes: wantsThemes,
6241
6434
  langs: wantsLangs
6242
- }).then((hh) => hh);
6435
+ }).then((hh) => {
6436
+ hh.__streamMonacoLoadedThemes = new Set(wantsThemes.map((t) => themeKey(t)));
6437
+ hh.__streamMonacoLoadedLangs = new Set(wantsLangs);
6438
+ return hh;
6439
+ });
6243
6440
  monacoHighlighterPromise = p;
6244
6441
  return p;
6245
6442
  }
@@ -6258,6 +6455,7 @@ function clearHighlighterCache() {
6258
6455
  monacoThemeByKey.clear();
6259
6456
  monacoLanguageSet.clear();
6260
6457
  themeRegisterPromise = null;
6458
+ instrumentedHighlighterCache = /* @__PURE__ */ new WeakMap();
6261
6459
  languagesRegistered = false;
6262
6460
  currentLanguages = [];
6263
6461
  }
@@ -6324,9 +6522,15 @@ async function getOrCreateHighlighter(themes, languages$1) {
6324
6522
  */
6325
6523
  async function registerMonacoThemes(themes, languages$1) {
6326
6524
  return enqueueRegistration(async () => {
6525
+ const registrationStartedAt = nowMs();
6526
+ let ensureHighlighterMs = 0;
6527
+ let patchMonacoMs = 0;
6528
+ let patchedMonaco = false;
6327
6529
  registerMonacoLanguages(languages$1);
6328
6530
  const p = (async () => {
6531
+ const ensureHighlighterStartedAt = nowMs();
6329
6532
  const highlighter = await ensureMonacoHighlighter(themes, languages$1);
6533
+ ensureHighlighterMs = nowMs() - ensureHighlighterStartedAt;
6330
6534
  const wantsLangs = Array.from(monacoLanguageSet.values());
6331
6535
  const needsLanguagePatch = lastPatchedHighlighter !== highlighter || wantsLangs.some((l) => !lastPatchedLanguages.has(l));
6332
6536
  if (needsLanguagePatch) {
@@ -6347,9 +6551,17 @@ async function registerMonacoThemes(themes, languages$1) {
6347
6551
  provider = {
6348
6552
  ...provider,
6349
6553
  tokenize(line, state) {
6554
+ const hook = getTokenizationPerfHook();
6555
+ const startedAt = hook ? nowMs() : 0;
6556
+ let tokenCount = 0;
6557
+ let failed = false;
6350
6558
  try {
6351
- return originalTokenize(line, state);
6559
+ const result = originalTokenize(line, state);
6560
+ tokenCount = Array.isArray(result === null || result === void 0 ? void 0 : result.tokens) ? result.tokens.length : 0;
6561
+ return result;
6352
6562
  } catch {
6563
+ failed = true;
6564
+ tokenCount = 1;
6353
6565
  return {
6354
6566
  endState: state,
6355
6567
  tokens: [{
@@ -6357,6 +6569,8 @@ async function registerMonacoThemes(themes, languages$1) {
6357
6569
  scopes: ""
6358
6570
  }]
6359
6571
  };
6572
+ } finally {
6573
+ if (hook) recordTokenize(hook, lang, nowMs() - startedAt, line, tokenCount, failed);
6360
6574
  }
6361
6575
  }
6362
6576
  };
@@ -6365,7 +6579,10 @@ async function registerMonacoThemes(themes, languages$1) {
6365
6579
  }
6366
6580
  }
6367
6581
  };
6368
- shikiToMonaco(highlighter, monacoProxy);
6582
+ const patchMonacoStartedAt = nowMs();
6583
+ shikiToMonaco(maybeInstrumentHighlighterGrammar(highlighter), monacoProxy);
6584
+ patchMonacoMs = nowMs() - patchMonacoStartedAt;
6585
+ patchedMonaco = true;
6369
6586
  lastPatchedHighlighter = highlighter;
6370
6587
  lastPatchedLanguages = new Set(wantsLangs);
6371
6588
  }
@@ -6375,6 +6592,14 @@ async function registerMonacoThemes(themes, languages$1) {
6375
6592
  setThemeRegisterPromise(p);
6376
6593
  try {
6377
6594
  const res = await p;
6595
+ recordThemeRegistration({
6596
+ durationMs: nowMs() - registrationStartedAt,
6597
+ ensureHighlighterMs,
6598
+ patchMonacoMs,
6599
+ themes: themes.length,
6600
+ languages: languages$1.length,
6601
+ patchedMonaco
6602
+ });
6378
6603
  return res;
6379
6604
  } catch (e) {
6380
6605
  setThemeRegisterPromise(null);
@@ -6508,7 +6733,8 @@ function useMonaco(monacoOptions = {}) {
6508
6733
  let modifiedModel = null;
6509
6734
  const themes = monacoOptions.themes && ((_monacoOptions$themes = monacoOptions.themes) === null || _monacoOptions$themes === void 0 ? void 0 : _monacoOptions$themes.length) ? monacoOptions.themes : defaultThemes;
6510
6735
  if (!Array.isArray(themes) || themes.length < 2) throw new Error("Monaco themes must be an array with at least two themes: [darkTheme, lightTheme]");
6511
- const languages$1 = monacoOptions.languages ?? defaultLanguages;
6736
+ const explicitLanguages = monacoOptions.languages;
6737
+ const languages$1 = explicitLanguages ?? defaultLanguages;
6512
6738
  const MAX_HEIGHT = monacoOptions.MAX_HEIGHT ?? 500;
6513
6739
  const autoScrollOnUpdate = monacoOptions.autoScrollOnUpdate ?? true;
6514
6740
  const autoScrollInitial = monacoOptions.autoScrollInitial ?? true;
@@ -6597,10 +6823,27 @@ function useMonaco(monacoOptions = {}) {
6597
6823
  console.warn("onThemeChange callback threw an error:", err);
6598
6824
  }
6599
6825
  }
6600
- async function ensureThemeRegistered(themeName) {
6826
+ function normalizeLanguage(language) {
6827
+ if (!language) return null;
6828
+ return processedLanguage(language) || language;
6829
+ }
6830
+ function resolveCreateLanguages(primaryLanguage) {
6831
+ const primary = normalizeLanguage(primaryLanguage);
6832
+ if (Array.isArray(explicitLanguages) && explicitLanguages.length) {
6833
+ const set = /* @__PURE__ */ new Set();
6834
+ for (const language of explicitLanguages) {
6835
+ const normalized = normalizeLanguage(language);
6836
+ if (normalized) set.add(normalized);
6837
+ }
6838
+ if (primary) set.add(primary);
6839
+ return Array.from(set);
6840
+ }
6841
+ return primary ? [primary] : ["typescript"];
6842
+ }
6843
+ async function ensureThemeRegistered(themeName, requestedLanguages = languages$1) {
6601
6844
  const availableNames = themes.map((t) => typeof t === "string" ? t : t.name);
6602
6845
  const list = availableNames.includes(themeName) ? themes : themes.concat(themeName);
6603
- await registerMonacoThemes(list, languages$1);
6846
+ await registerMonacoThemes(list, requestedLanguages);
6604
6847
  }
6605
6848
  function resolveRequestedThemeName() {
6606
6849
  return requestedThemeName ?? globalRequestedThemeName ?? monacoOptions.theme ?? currentTheme.value;
@@ -6677,11 +6920,12 @@ function useMonaco(monacoOptions = {}) {
6677
6920
  queuedEditorUpdateDuringCreate = null;
6678
6921
  disposeAllPendingCreateDisposables();
6679
6922
  }
6680
- async function resolveCreateThemeName(requestId, kind) {
6923
+ async function resolveCreateThemeName(requestId, kind, primaryLanguage) {
6681
6924
  let themeName = resolveRequestedThemeName();
6925
+ const createLanguages = resolveCreateLanguages(primaryLanguage);
6682
6926
  while (true) {
6683
6927
  assertCreateStillActive(requestId, kind);
6684
- await ensureThemeRegistered(themeName);
6928
+ await ensureThemeRegistered(themeName, createLanguages);
6685
6929
  assertCreateStillActive(requestId, kind);
6686
6930
  const latestThemeName = resolveRequestedThemeName();
6687
6931
  if (latestThemeName === themeName) return themeName;
@@ -6700,7 +6944,7 @@ function useMonaco(monacoOptions = {}) {
6700
6944
  if (requestDisposables.length) pendingCreateDisposables.set(requestId, requestDisposables);
6701
6945
  let nextEditorMgr = null;
6702
6946
  try {
6703
- const initialThemeName = await resolveCreateThemeName(requestId, "editor");
6947
+ const initialThemeName = await resolveCreateThemeName(requestId, "editor", language);
6704
6948
  nextEditorMgr = new EditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, monacoOptions.revealDebounceMs, monacoOptions.updateThrottleMs);
6705
6949
  const nextEditorView = await nextEditorMgr.createEditor(container, code, language, initialThemeName);
6706
6950
  assertCreateStillActive(requestId, "editor");
@@ -6747,7 +6991,7 @@ function useMonaco(monacoOptions = {}) {
6747
6991
  if (requestDisposables.length) pendingCreateDisposables.set(requestId, requestDisposables);
6748
6992
  let nextDiffMgr = null;
6749
6993
  try {
6750
- const initialThemeName = await resolveCreateThemeName(requestId, "diff");
6994
+ const initialThemeName = await resolveCreateThemeName(requestId, "diff", language);
6751
6995
  nextDiffMgr = new DiffEditorManager(monacoOptions, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, diffAutoScroll, monacoOptions.revealDebounceMs, monacoOptions.diffUpdateThrottleMs);
6752
6996
  const nextDiffEditorView = await nextDiffMgr.createDiffEditor(container, originalCode, modifiedCode, language, initialThemeName);
6753
6997
  assertCreateStillActive(requestId, "diff");