stream-monaco 0.0.2 → 0.0.4

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
@@ -29,6 +29,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
 
30
30
  //#endregion
31
31
  const monaco_editor = __toESM(require("monaco-editor"));
32
+ const node_process = __toESM(require("node:process"));
32
33
  const alien_signals = __toESM(require("alien-signals"));
33
34
  const __shikijs_monaco = __toESM(require("@shikijs/monaco"));
34
35
  const shiki = __toESM(require("shiki"));
@@ -227,34 +228,107 @@ __export(monaco_shim_exports, { default: () => monaco });
227
228
  __reExport(monaco_shim_exports, require("monaco-editor"));
228
229
  const monaco = monaco_editor;
229
230
 
231
+ //#endregion
232
+ //#region src/utils/logger.ts
233
+ let seq = 0;
234
+ const DEBUG = (() => {
235
+ try {
236
+ if (typeof window !== "undefined" && window.__STREAM_MONACO_DEBUG__ !== void 0) return Boolean(window.__STREAM_MONACO_DEBUG__);
237
+ try {
238
+ const proc = node_process.default;
239
+ if (proc && proc.env && proc.env.NODE_ENV === "production") return false;
240
+ } catch {}
241
+ } catch {}
242
+ return true;
243
+ })();
244
+ function log(tag, ...args) {
245
+ if (!DEBUG) return;
246
+ try {
247
+ seq += 1;
248
+ const id = `#${seq}`;
249
+ const ts = typeof performance !== "undefined" && performance.now ? performance.now().toFixed(1) : Date.now();
250
+ console.warn(`${id} [${tag}] @${ts}ms`, ...args);
251
+ } catch (err) {
252
+ try {
253
+ console.warn("[logger] fallback", tag, ...args, err);
254
+ } catch {}
255
+ }
256
+ }
257
+ function error(tag, ...args) {
258
+ if (!DEBUG) return;
259
+ try {
260
+ console.error(`[${tag}]`, ...args);
261
+ } catch (err) {
262
+ try {
263
+ console.error("[logger] fallback error", tag, ...args, err);
264
+ } catch {}
265
+ }
266
+ }
267
+
230
268
  //#endregion
231
269
  //#region src/utils/height.ts
232
270
  function createHeightManager(container, computeNext) {
233
271
  let raf = null;
272
+ let debounceTimer = null;
234
273
  let lastApplied = -1;
235
274
  let suppressed = false;
275
+ const HYSTERESIS_PX = 12;
276
+ const DEBOUNCE_MS = 0;
236
277
  function apply() {
237
278
  const next = computeNext();
279
+ if (next == null) return;
280
+ log("heightManager", "computeNext ->", {
281
+ next,
282
+ lastApplied
283
+ });
284
+ if (!Number.isFinite(next) || next <= 0) {
285
+ log("heightManager", "invalid next height, ignoring", next);
286
+ return;
287
+ }
288
+ if (lastApplied !== -1 && Math.abs(next - lastApplied) <= HYSTERESIS_PX) return;
238
289
  if (next === lastApplied) return;
239
290
  suppressed = true;
240
291
  container.style.height = `${next}px`;
241
292
  lastApplied = next;
293
+ log("heightManager", "applied height ->", next);
242
294
  queueMicrotask(() => {
243
295
  suppressed = false;
244
296
  });
245
297
  }
298
+ function scheduleApply() {
299
+ if (debounceTimer != null) {
300
+ clearTimeout(debounceTimer);
301
+ debounceTimer = null;
302
+ }
303
+ if (DEBOUNCE_MS === 0) {
304
+ if (raf != null) return;
305
+ raf = requestAnimationFrame(() => {
306
+ raf = null;
307
+ apply();
308
+ });
309
+ return;
310
+ }
311
+ debounceTimer = setTimeout(() => {
312
+ debounceTimer = null;
313
+ if (raf != null) return;
314
+ raf = requestAnimationFrame(() => {
315
+ raf = null;
316
+ apply();
317
+ });
318
+ }, DEBOUNCE_MS);
319
+ }
246
320
  function update() {
247
- if (raf != null) return;
248
- raf = requestAnimationFrame(() => {
249
- raf = null;
250
- apply();
251
- });
321
+ scheduleApply();
252
322
  }
253
323
  function dispose() {
254
324
  if (raf != null) {
255
325
  cancelAnimationFrame(raf);
256
326
  raf = null;
257
327
  }
328
+ if (debounceTimer != null) {
329
+ clearTimeout(debounceTimer);
330
+ debounceTimer = null;
331
+ }
258
332
  }
259
333
  function isSuppressed() {
260
334
  return suppressed;
@@ -310,18 +384,105 @@ function createScrollWatcherForEditor(ed, opts) {
310
384
  var _ed$getScrollTop, _ed$onDidScrollChange;
311
385
  const initial = ((_ed$getScrollTop = ed.getScrollTop) === null || _ed$getScrollTop === void 0 ? void 0 : _ed$getScrollTop.call(ed)) ?? 0;
312
386
  opts.setLast(initial);
313
- const disp = ((_ed$onDidScrollChange = ed.onDidScrollChange) === null || _ed$onDidScrollChange === void 0 ? void 0 : _ed$onDidScrollChange.call(ed, (e) => {
387
+ log("scrollWatcher", "initial scrollTop=", initial);
388
+ let suppressedExternally = false;
389
+ const THRESHOLD_PX = 6;
390
+ let domNode = null;
391
+ let interactionListener = null;
392
+ const listener = (e) => {
314
393
  var _ed$getScrollTop2;
394
+ if (suppressedExternally) {
395
+ log("scrollWatcher", "suppressedExternally, ignoring event");
396
+ return;
397
+ }
315
398
  const currentTop = e && typeof e.scrollTop === "number" ? e.scrollTop : ((_ed$getScrollTop2 = ed.getScrollTop) === null || _ed$getScrollTop2 === void 0 ? void 0 : _ed$getScrollTop2.call(ed)) ?? 0;
316
399
  const delta = currentTop - opts.getLast();
317
400
  opts.setLast(currentTop);
401
+ if (Math.abs(delta) < THRESHOLD_PX) {
402
+ log("scrollWatcher", "small delta ignored", delta);
403
+ try {
404
+ const scrollHeight = typeof ed.getScrollHeight === "function" ? ed.getScrollHeight() : void 0;
405
+ const li = typeof ed.getLayoutInfo === "function" ? ed.getLayoutInfo() : void 0;
406
+ const viewportH = (li === null || li === void 0 ? void 0 : li.height) ?? void 0;
407
+ if (typeof scrollHeight === "number" && typeof viewportH === "number") {
408
+ const distance = scrollHeight - (currentTop + viewportH);
409
+ if (distance <= Math.max(THRESHOLD_PX, 0)) {
410
+ log("scrollWatcher", "small delta but at bottom, maybe resume", { distance });
411
+ opts.onMaybeResume();
412
+ }
413
+ }
414
+ } catch {}
415
+ return;
416
+ }
417
+ log("scrollWatcher", "delta=", delta, "currentTop=", currentTop);
318
418
  if (delta < 0) {
419
+ log("scrollWatcher", "pause detected delta=", delta);
319
420
  opts.onPause();
320
421
  return;
321
422
  }
423
+ log("scrollWatcher", "maybe resume delta=", delta);
322
424
  opts.onMaybeResume();
323
- })) ?? null;
324
- return disp;
425
+ };
426
+ const disp = ((_ed$onDidScrollChange = ed.onDidScrollChange) === null || _ed$onDidScrollChange === void 0 ? void 0 : _ed$onDidScrollChange.call(ed, listener)) ?? null;
427
+ const api = {
428
+ dispose() {
429
+ try {
430
+ if (disp && typeof disp.dispose === "function") disp.dispose();
431
+ else if (typeof disp === "function") disp();
432
+ } catch {}
433
+ log("scrollWatcher", "dispose");
434
+ },
435
+ setSuppressed(v) {
436
+ const newVal = !!v;
437
+ if (newVal === suppressedExternally) return;
438
+ suppressedExternally = newVal;
439
+ log("scrollWatcher", "setSuppressed =>", suppressedExternally);
440
+ try {
441
+ if (!domNode && typeof ed.getDomNode === "function") domNode = ed.getDomNode();
442
+ if (suppressedExternally && domNode) {
443
+ if (!interactionListener) {
444
+ interactionListener = () => {
445
+ try {
446
+ var _ed$getScrollTop3;
447
+ log("scrollWatcher", "user interaction detected while suppressed, cancelling suppression");
448
+ opts.onPause();
449
+ suppressedExternally = false;
450
+ const cur = ((_ed$getScrollTop3 = ed.getScrollTop) === null || _ed$getScrollTop3 === void 0 ? void 0 : _ed$getScrollTop3.call(ed)) ?? 0;
451
+ opts.setLast(cur);
452
+ try {
453
+ const scrollHeight = typeof ed.getScrollHeight === "function" ? ed.getScrollHeight() : void 0;
454
+ const li = typeof ed.getLayoutInfo === "function" ? ed.getLayoutInfo() : void 0;
455
+ const viewportH = (li === null || li === void 0 ? void 0 : li.height) ?? void 0;
456
+ if (typeof scrollHeight === "number" && typeof viewportH === "number") {
457
+ const distance = scrollHeight - (cur + viewportH);
458
+ if (distance <= Math.max(THRESHOLD_PX, 0)) {
459
+ log("scrollWatcher", "interaction moved to bottom, maybe resume", { distance });
460
+ opts.onMaybeResume();
461
+ }
462
+ }
463
+ } catch {}
464
+ if (domNode && interactionListener) {
465
+ domNode.removeEventListener("wheel", interactionListener, { passive: true });
466
+ domNode.removeEventListener("pointerdown", interactionListener);
467
+ domNode.removeEventListener("touchstart", interactionListener);
468
+ }
469
+ interactionListener = null;
470
+ } catch {}
471
+ };
472
+ domNode.addEventListener("wheel", interactionListener, { passive: true });
473
+ domNode.addEventListener("pointerdown", interactionListener);
474
+ domNode.addEventListener("touchstart", interactionListener);
475
+ }
476
+ } else if (domNode && interactionListener) {
477
+ domNode.removeEventListener("wheel", interactionListener, { passive: true });
478
+ domNode.removeEventListener("pointerdown", interactionListener);
479
+ domNode.removeEventListener("touchstart", interactionListener);
480
+ interactionListener = null;
481
+ }
482
+ } catch {}
483
+ }
484
+ };
485
+ return api;
325
486
  }
326
487
 
327
488
  //#endregion
@@ -366,11 +527,14 @@ var DiffEditorManager = class {
366
527
  };
367
528
  }
368
529
  lastRevealLineDiff = null;
530
+ revealTicketDiff = 0;
369
531
  revealDebounceIdDiff = null;
370
532
  revealDebounceMs = defaultRevealDebounceMs;
371
533
  revealIdleTimerIdDiff = null;
372
534
  revealStrategyOption;
373
535
  revealBatchOnIdleMsOption;
536
+ scrollWatcherSuppressionMs = 500;
537
+ diffScrollWatcherSuppressionTimer = null;
374
538
  appendBufferDiff = [];
375
539
  appendBufferDiffScheduled = false;
376
540
  rafScheduler = createRafScheduler();
@@ -400,6 +564,26 @@ var DiffEditorManager = class {
400
564
  const desired = Math.max(fromLines, scrollH);
401
565
  return Math.min(desired, this.maxHeightValue);
402
566
  }
567
+ isOverflowAutoDiff() {
568
+ return !!this.lastContainer && this.lastContainer.style.overflow === "auto";
569
+ }
570
+ shouldPerformImmediateRevealDiff() {
571
+ return this.autoScrollOnUpdate && this.shouldAutoScrollDiff && this.hasVerticalScrollbarModified() && this.isOverflowAutoDiff();
572
+ }
573
+ suppressScrollWatcherDiff(ms) {
574
+ if (!this.diffScrollWatcher || typeof this.diffScrollWatcher.setSuppressed !== "function") return;
575
+ if (this.diffScrollWatcherSuppressionTimer != null) {
576
+ clearTimeout(this.diffScrollWatcherSuppressionTimer);
577
+ this.diffScrollWatcherSuppressionTimer = null;
578
+ }
579
+ this.diffScrollWatcher.setSuppressed(true);
580
+ this.diffScrollWatcherSuppressionTimer = setTimeout(() => {
581
+ try {
582
+ this.diffScrollWatcher.setSuppressed(false);
583
+ } catch {}
584
+ this.diffScrollWatcherSuppressionTimer = null;
585
+ }, ms);
586
+ }
403
587
  hasVerticalScrollbarModified() {
404
588
  if (!this.diffEditorView) return false;
405
589
  if (this._hasScrollBar) return true;
@@ -419,21 +603,56 @@ var DiffEditorManager = class {
419
603
  }
420
604
  maybeScrollDiffToBottom(targetLine, prevLineOverride) {
421
605
  this.rafScheduler.schedule("maybe-scroll-diff", () => {
606
+ log("diff", "maybeScrollDiffToBottom called", {
607
+ targetLine,
608
+ prevLineOverride,
609
+ diffAutoScroll: this.diffAutoScroll,
610
+ autoScrollOnUpdate: this.autoScrollOnUpdate,
611
+ shouldAutoScrollDiff: this.shouldAutoScrollDiff
612
+ });
422
613
  if (!this.diffEditorView) return;
423
- if (!(this.diffAutoScroll && this.autoScrollOnUpdate && this.shouldAutoScrollDiff && this.hasVerticalScrollbarModified())) return;
614
+ const hasV = this.hasVerticalScrollbarModified();
615
+ log("diff", "hasVerticalScrollbarModified ->", hasV);
616
+ if (!(this.diffAutoScroll && this.autoScrollOnUpdate && this.shouldAutoScrollDiff && hasV)) return;
424
617
  const me = this.diffEditorView.getModifiedEditor();
425
618
  const model = me.getModel();
426
619
  const currentLine = (model === null || model === void 0 ? void 0 : model.getLineCount()) ?? 1;
427
620
  const line = targetLine ?? currentLine;
428
621
  const prevLine = typeof prevLineOverride === "number" ? prevLineOverride : this.lastKnownModifiedLineCount ?? -1;
622
+ log("diff", "scroll metrics", {
623
+ prevLine,
624
+ currentLine,
625
+ line,
626
+ lastRevealLineDiff: this.lastRevealLineDiff
627
+ });
429
628
  if (prevLine !== -1 && prevLine === currentLine && line === currentLine) return;
430
629
  if (this.lastRevealLineDiff !== null && this.lastRevealLineDiff === line) return;
431
630
  const batchMs = this.revealBatchOnIdleMsOption ?? this.options.revealBatchOnIdleMs ?? defaultRevealBatchOnIdleMs;
631
+ log("diff", "reveal timing", {
632
+ batchMs,
633
+ revealDebounceMs: this.revealDebounceMs,
634
+ revealDebounceMsOption: this.revealDebounceMsOption
635
+ });
432
636
  if (typeof batchMs === "number" && batchMs > 0) {
637
+ if (hasV) {
638
+ const ticket$1 = ++this.revealTicketDiff;
639
+ log("diff", "has scrollbar -> immediate ticketed reveal", {
640
+ ticket: ticket$1,
641
+ line
642
+ });
643
+ this.performRevealDiffTicketed(line, ticket$1);
644
+ return;
645
+ }
433
646
  if (this.revealIdleTimerIdDiff != null) clearTimeout(this.revealIdleTimerIdDiff);
647
+ const ticket = ++this.revealTicketDiff;
648
+ log("diff", "scheduling idle reveal", {
649
+ ticket,
650
+ batchMs,
651
+ line
652
+ });
434
653
  this.revealIdleTimerIdDiff = setTimeout(() => {
435
654
  this.revealIdleTimerIdDiff = null;
436
- this.performRevealDiff(line);
655
+ this.performRevealDiffTicketed(line, ticket);
437
656
  }, batchMs);
438
657
  return;
439
658
  }
@@ -444,14 +663,32 @@ var DiffEditorManager = class {
444
663
  const ms = typeof this.revealDebounceMs === "number" && this.revealDebounceMs > 0 ? this.revealDebounceMs : typeof this.revealDebounceMsOption === "number" && this.revealDebounceMsOption > 0 ? this.revealDebounceMsOption : this.revealDebounceMs;
445
664
  this.revealDebounceIdDiff = setTimeout(() => {
446
665
  this.revealDebounceIdDiff = null;
447
- this.performRevealDiff(line);
666
+ const ticket = ++this.revealTicketDiff;
667
+ log("diff", "debounced reveal firing", {
668
+ ticket,
669
+ line
670
+ });
671
+ this.performRevealDiffTicketed(line, ticket);
448
672
  }, ms);
449
673
  this.lastKnownModifiedLineCount = currentLine;
450
674
  });
451
675
  }
452
- performRevealDiff(line) {
676
+ performRevealDiffTicketed(line, ticket) {
453
677
  this.rafScheduler.schedule("revealDiff", () => {
454
678
  var _editor;
679
+ if (this.diffScrollWatcher) {
680
+ log("diff", "performRevealDiffTicketed - suppressing watcher", {
681
+ ticket,
682
+ line,
683
+ ms: this.scrollWatcherSuppressionMs
684
+ });
685
+ this.suppressScrollWatcherDiff(this.scrollWatcherSuppressionMs);
686
+ }
687
+ if (ticket !== this.revealTicketDiff) return;
688
+ log("diff", "performRevealDiffTicketed - performing reveal", {
689
+ ticket,
690
+ line
691
+ });
455
692
  const strategy = this.revealStrategyOption ?? this.options.revealStrategy ?? "centerIfOutside";
456
693
  const ScrollType = monaco_shim_exports.ScrollType || ((_editor = monaco_shim_exports.editor) === null || _editor === void 0 ? void 0 : _editor.ScrollType);
457
694
  const smooth = ScrollType && typeof ScrollType.Smooth !== "undefined" ? ScrollType.Smooth : void 0;
@@ -469,13 +706,71 @@ var DiffEditorManager = class {
469
706
  } catch {}
470
707
  }
471
708
  this.lastRevealLineDiff = line;
709
+ log("diff", "performRevealDiffTicketed - revealed", {
710
+ line,
711
+ lastRevealLineDiff: this.lastRevealLineDiff
712
+ });
713
+ try {
714
+ var _this$diffEditorView, _this$diffEditorView$, _this$diffEditorView$2;
715
+ this.shouldAutoScrollDiff = true;
716
+ this.lastScrollTopDiff = ((_this$diffEditorView = this.diffEditorView) === null || _this$diffEditorView === void 0 || (_this$diffEditorView$2 = (_this$diffEditorView$ = _this$diffEditorView.getModifiedEditor()).getScrollTop) === null || _this$diffEditorView$2 === void 0 ? void 0 : _this$diffEditorView$2.call(_this$diffEditorView$)) ?? this.lastScrollTopDiff;
717
+ } catch {}
718
+ });
719
+ }
720
+ performImmediateRevealDiff(line, ticket) {
721
+ var _editor2;
722
+ if (!this.diffEditorView) return;
723
+ if (ticket !== this.revealTicketDiff) return;
724
+ const ScrollType = monaco_shim_exports.ScrollType || ((_editor2 = monaco_shim_exports.editor) === null || _editor2 === void 0 ? void 0 : _editor2.ScrollType);
725
+ const immediate = ScrollType && typeof ScrollType.Immediate !== "undefined" ? ScrollType.Immediate : void 0;
726
+ const me = this.diffEditorView.getModifiedEditor();
727
+ if (typeof immediate !== "undefined") me.revealLine(line, immediate);
728
+ else me.revealLine(line);
729
+ this.measureViewportDiff();
730
+ log("diff", "performImmediateRevealDiff", {
731
+ line,
732
+ ticket
733
+ });
734
+ try {
735
+ var _this$diffEditorView2, _this$diffEditorView3, _this$diffEditorView4;
736
+ this.shouldAutoScrollDiff = true;
737
+ this.lastScrollTopDiff = ((_this$diffEditorView2 = this.diffEditorView) === null || _this$diffEditorView2 === void 0 || (_this$diffEditorView4 = (_this$diffEditorView3 = _this$diffEditorView2.getModifiedEditor()).getScrollTop) === null || _this$diffEditorView4 === void 0 ? void 0 : _this$diffEditorView4.call(_this$diffEditorView3)) ?? this.lastScrollTopDiff;
738
+ } catch {}
739
+ }
740
+ scheduleImmediateRevealAfterLayoutDiff(line) {
741
+ const ticket = ++this.revealTicketDiff;
742
+ this.rafScheduler.schedule("immediate-reveal-diff", async () => {
743
+ const target = this.diffEditorView && this.diffHeightManager ? Math.min(this.computedHeight(), this.maxHeightValue) : -1;
744
+ if (target !== -1 && this.diffHeightManager) {
745
+ if (this.lastContainer) this.lastContainer.style.height = `${target}px`;
746
+ await this.waitForHeightAppliedDiff(target);
747
+ }
748
+ this.performImmediateRevealDiff(line, ticket);
749
+ });
750
+ }
751
+ waitForHeightAppliedDiff(target, timeoutMs = 500) {
752
+ return new Promise((resolve) => {
753
+ const start = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
754
+ const check = () => {
755
+ const applied = this.lastContainer ? Number.parseFloat((this.lastContainer.style.height || "").replace("px", "")) || 0 : -1;
756
+ if (applied >= target - 1) {
757
+ resolve();
758
+ return;
759
+ }
760
+ if ((typeof performance !== "undefined" && performance.now ? performance.now() : Date.now()) - start > timeoutMs) {
761
+ resolve();
762
+ return;
763
+ }
764
+ requestAnimationFrame(check);
765
+ };
766
+ check();
472
767
  });
473
768
  }
474
769
  async createDiffEditor(container, originalCode, modifiedCode, language, currentTheme) {
475
770
  var _me$getScrollHeight2, _me$getOption, _oEditor$onDidContent, _mEditor$onDidContent;
476
771
  this.cleanup();
477
772
  this.lastContainer = container;
478
- container.style.overflow = "auto";
773
+ container.style.overflow = "hidden";
479
774
  container.style.maxHeight = this.maxHeightCSS;
480
775
  const lang = processedLanguage(language) || language;
481
776
  this.originalModel = monaco_shim_exports.editor.createModel(originalCode, lang);
@@ -524,13 +819,23 @@ var DiffEditorManager = class {
524
819
  }
525
820
  });
526
821
  }
527
- this.maybeScrollDiffToBottom(this.modifiedModel.getLineCount(), this.lastKnownModifiedLineCount ?? void 0);
822
+ log("diff", "createDiffEditor", {
823
+ autoScrollInitial: this.autoScrollInitial,
824
+ diffAutoScroll: this.diffAutoScroll
825
+ });
826
+ const MIN_VISIBLE_HEIGHT = Math.min(120, this.maxHeightValue);
827
+ container.style.minHeight = `${MIN_VISIBLE_HEIGHT}px`;
528
828
  if (this.diffHeightManager) {
529
829
  this.diffHeightManager.dispose();
530
830
  this.diffHeightManager = null;
531
831
  }
532
832
  this.diffHeightManager = createHeightManager(container, () => this.computedHeight());
533
833
  this.diffHeightManager.update();
834
+ const initialComputed = this.computedHeight();
835
+ if (initialComputed >= this.maxHeightValue - 1) {
836
+ container.style.height = `${this.maxHeightValue}px`;
837
+ container.style.overflow = "auto";
838
+ }
534
839
  const me = this.diffEditorView.getModifiedEditor();
535
840
  this.cachedScrollHeightDiff = ((_me$getScrollHeight2 = me.getScrollHeight) === null || _me$getScrollHeight2 === void 0 ? void 0 : _me$getScrollHeight2.call(me)) ?? null;
536
841
  this.cachedLineHeightDiff = ((_me$getOption = me.getOption) === null || _me$getOption === void 0 ? void 0 : _me$getOption.call(me, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? null;
@@ -540,33 +845,54 @@ var DiffEditorManager = class {
540
845
  (_oEditor$onDidContent = oEditor.onDidContentSizeChange) === null || _oEditor$onDidContent === void 0 || _oEditor$onDidContent.call(oEditor, () => {
541
846
  this._hasScrollBar = false;
542
847
  this.rafScheduler.schedule("content-size-change-diff", () => {
543
- try {
544
- var _oEditor$getScrollHei, _oEditor$getOption, _this$diffHeightManag, _this$diffHeightManag2;
545
- this.cachedScrollHeightDiff = ((_oEditor$getScrollHei = oEditor.getScrollHeight) === null || _oEditor$getScrollHei === void 0 ? void 0 : _oEditor$getScrollHei.call(oEditor)) ?? this.cachedScrollHeightDiff;
546
- this.cachedLineHeightDiff = ((_oEditor$getOption = oEditor.getOption) === null || _oEditor$getOption === void 0 ? void 0 : _oEditor$getOption.call(oEditor, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? this.cachedLineHeightDiff;
547
- this.cachedComputedHeightDiff = this.computedHeight();
548
- if ((_this$diffHeightManag = this.diffHeightManager) === null || _this$diffHeightManag === void 0 ? void 0 : _this$diffHeightManag.isSuppressed()) return;
549
- (_this$diffHeightManag2 = this.diffHeightManager) === null || _this$diffHeightManag2 === void 0 || _this$diffHeightManag2.update();
550
- } catch {}
848
+ var _oEditor$getScrollHei, _oEditor$getOption, _this$diffHeightManag, _this$diffHeightManag2;
849
+ this.cachedScrollHeightDiff = ((_oEditor$getScrollHei = oEditor.getScrollHeight) === null || _oEditor$getScrollHei === void 0 ? void 0 : _oEditor$getScrollHei.call(oEditor)) ?? this.cachedScrollHeightDiff;
850
+ this.cachedLineHeightDiff = ((_oEditor$getOption = oEditor.getOption) === null || _oEditor$getOption === void 0 ? void 0 : _oEditor$getOption.call(oEditor, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? this.cachedLineHeightDiff;
851
+ this.cachedComputedHeightDiff = this.computedHeight();
852
+ if ((_this$diffHeightManag = this.diffHeightManager) === null || _this$diffHeightManag === void 0 ? void 0 : _this$diffHeightManag.isSuppressed()) return;
853
+ (_this$diffHeightManag2 = this.diffHeightManager) === null || _this$diffHeightManag2 === void 0 || _this$diffHeightManag2.update();
854
+ const computed$1 = this.computedHeight();
855
+ if (this.lastContainer) {
856
+ const prevOverflow = this.lastContainer.style.overflow;
857
+ const newOverflow = computed$1 >= this.maxHeightValue - 1 ? "auto" : "hidden";
858
+ if (prevOverflow !== newOverflow) {
859
+ this.lastContainer.style.overflow = newOverflow;
860
+ if (newOverflow === "auto" && this.shouldAutoScrollDiff) {
861
+ var _this$modifiedModel;
862
+ this.maybeScrollDiffToBottom((_this$modifiedModel = this.modifiedModel) === null || _this$modifiedModel === void 0 ? void 0 : _this$modifiedModel.getLineCount());
863
+ }
864
+ }
865
+ }
551
866
  });
552
867
  });
553
868
  (_mEditor$onDidContent = mEditor.onDidContentSizeChange) === null || _mEditor$onDidContent === void 0 || _mEditor$onDidContent.call(mEditor, () => {
554
869
  this._hasScrollBar = false;
555
870
  this.rafScheduler.schedule("content-size-change-diff", () => {
556
- try {
557
- var _mEditor$getScrollHei, _mEditor$getOption, _this$diffHeightManag3, _this$diffHeightManag4;
558
- this.cachedScrollHeightDiff = ((_mEditor$getScrollHei = mEditor.getScrollHeight) === null || _mEditor$getScrollHei === void 0 ? void 0 : _mEditor$getScrollHei.call(mEditor)) ?? this.cachedScrollHeightDiff;
559
- this.cachedLineHeightDiff = ((_mEditor$getOption = mEditor.getOption) === null || _mEditor$getOption === void 0 ? void 0 : _mEditor$getOption.call(mEditor, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? this.cachedLineHeightDiff;
560
- this.cachedComputedHeightDiff = this.computedHeight();
561
- if ((_this$diffHeightManag3 = this.diffHeightManager) === null || _this$diffHeightManag3 === void 0 ? void 0 : _this$diffHeightManag3.isSuppressed()) return;
562
- (_this$diffHeightManag4 = this.diffHeightManager) === null || _this$diffHeightManag4 === void 0 || _this$diffHeightManag4.update();
563
- } catch {}
871
+ var _mEditor$getScrollHei, _mEditor$getOption, _this$diffHeightManag3, _this$diffHeightManag4;
872
+ this.cachedScrollHeightDiff = ((_mEditor$getScrollHei = mEditor.getScrollHeight) === null || _mEditor$getScrollHei === void 0 ? void 0 : _mEditor$getScrollHei.call(mEditor)) ?? this.cachedScrollHeightDiff;
873
+ this.cachedLineHeightDiff = ((_mEditor$getOption = mEditor.getOption) === null || _mEditor$getOption === void 0 ? void 0 : _mEditor$getOption.call(mEditor, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? this.cachedLineHeightDiff;
874
+ this.cachedComputedHeightDiff = this.computedHeight();
875
+ if ((_this$diffHeightManag3 = this.diffHeightManager) === null || _this$diffHeightManag3 === void 0 ? void 0 : _this$diffHeightManag3.isSuppressed()) return;
876
+ (_this$diffHeightManag4 = this.diffHeightManager) === null || _this$diffHeightManag4 === void 0 || _this$diffHeightManag4.update();
877
+ const computed$1 = this.computedHeight();
878
+ if (this.lastContainer) {
879
+ const prevOverflow = this.lastContainer.style.overflow;
880
+ const newOverflow = computed$1 >= this.maxHeightValue - 1 ? "auto" : "hidden";
881
+ if (prevOverflow !== newOverflow) {
882
+ this.lastContainer.style.overflow = newOverflow;
883
+ if (newOverflow === "auto" && this.shouldAutoScrollDiff) {
884
+ var _this$modifiedModel2;
885
+ this.maybeScrollDiffToBottom((_this$modifiedModel2 = this.modifiedModel) === null || _this$modifiedModel2 === void 0 ? void 0 : _this$modifiedModel2.getLineCount());
886
+ }
887
+ }
888
+ }
564
889
  });
565
890
  });
566
891
  mEditor.onDidChangeModelContent(() => {
567
892
  this.lastKnownModifiedDirty = true;
568
893
  this.rafScheduler.schedule("sync-last-known-modified", () => this.syncLastKnownModified());
569
894
  });
895
+ this.maybeScrollDiffToBottom(this.modifiedModel.getLineCount(), this.lastKnownModifiedLineCount ?? void 0);
570
896
  return this.diffEditorView;
571
897
  }
572
898
  updateDiff(originalCode, modifiedCode, codeLanguage) {
@@ -626,11 +952,37 @@ var DiffEditorManager = class {
626
952
  }
627
953
  const prev = this.lastKnownModifiedCode ?? this.modifiedModel.getValue();
628
954
  if (prev === newCode) return;
955
+ const prevLine = this.modifiedModel.getLineCount();
629
956
  if (newCode.startsWith(prev) && prev.length < newCode.length) {
630
- const prevLine = this.modifiedModel.getLineCount();
631
957
  this.appendToModel(this.modifiedModel, newCode.slice(prev.length));
632
958
  this.maybeScrollDiffToBottom(this.modifiedModel.getLineCount(), prevLine);
633
- } else this.applyMinimalEditToModel(this.modifiedModel, prev, newCode);
959
+ } else {
960
+ this.applyMinimalEditToModel(this.modifiedModel, prev, newCode);
961
+ const newLine = this.modifiedModel.getLineCount();
962
+ if (newLine !== prevLine) {
963
+ const shouldImmediate = this.shouldPerformImmediateRevealDiff();
964
+ if (shouldImmediate) this.suppressScrollWatcherDiff(this.scrollWatcherSuppressionMs + 800);
965
+ const computed$1 = this.computedHeight();
966
+ if (computed$1 >= this.maxHeightValue - 1 && this.lastContainer) {
967
+ this.lastContainer.style.height = `${this.maxHeightValue}px`;
968
+ this.lastContainer.style.overflow = "auto";
969
+ }
970
+ if (shouldImmediate) this.scheduleImmediateRevealAfterLayoutDiff(newLine);
971
+ else this.maybeScrollDiffToBottom(newLine, prevLine);
972
+ if (this.autoScrollOnUpdate && this.shouldAutoScrollDiff) try {
973
+ var _editor3, _me2$getModel, _me2$getScrollTop;
974
+ const ScrollType = monaco_shim_exports.ScrollType || ((_editor3 = monaco_shim_exports.editor) === null || _editor3 === void 0 ? void 0 : _editor3.ScrollType);
975
+ const immediate = ScrollType && typeof ScrollType.Immediate !== "undefined" ? ScrollType.Immediate : void 0;
976
+ const me2 = this.diffEditorView.getModifiedEditor();
977
+ const targetLine = ((_me2$getModel = me2.getModel()) === null || _me2$getModel === void 0 ? void 0 : _me2$getModel.getLineCount()) ?? newLine;
978
+ if (typeof immediate !== "undefined") me2.revealLine(targetLine, immediate);
979
+ else me2.revealLine(targetLine);
980
+ this.lastRevealLineDiff = targetLine;
981
+ this.shouldAutoScrollDiff = true;
982
+ this.lastScrollTopDiff = ((_me2$getScrollTop = me2.getScrollTop) === null || _me2$getScrollTop === void 0 ? void 0 : _me2$getScrollTop.call(me2)) ?? this.lastScrollTopDiff;
983
+ } catch {}
984
+ }
985
+ }
634
986
  this.lastKnownModifiedCode = newCode;
635
987
  }
636
988
  appendOriginal(appendText, codeLanguage) {
@@ -640,9 +992,7 @@ var DiffEditorManager = class {
640
992
  if (lang && this.originalModel.getLanguageId() !== lang) monaco_shim_exports.editor.setModelLanguage(this.originalModel, lang);
641
993
  }
642
994
  this.appendToModel(this.originalModel, appendText);
643
- try {
644
- this.lastKnownOriginalCode = this.originalModel.getValue();
645
- } catch {}
995
+ this.lastKnownOriginalCode = this.originalModel.getValue();
646
996
  }
647
997
  appendModified(appendText, codeLanguage) {
648
998
  if (!this.diffEditorView || !this.modifiedModel || !appendText) return;
@@ -711,6 +1061,15 @@ var DiffEditorManager = class {
711
1061
  clearTimeout(this.revealDebounceIdDiff);
712
1062
  this.revealDebounceIdDiff = null;
713
1063
  }
1064
+ if (this.revealIdleTimerIdDiff != null) {
1065
+ clearTimeout(this.revealIdleTimerIdDiff);
1066
+ this.revealIdleTimerIdDiff = null;
1067
+ }
1068
+ if (this.diffScrollWatcherSuppressionTimer != null) {
1069
+ clearTimeout(this.diffScrollWatcherSuppressionTimer);
1070
+ this.diffScrollWatcherSuppressionTimer = null;
1071
+ }
1072
+ this.revealTicketDiff = 0;
714
1073
  this.lastRevealLineDiff = null;
715
1074
  }
716
1075
  safeClean() {
@@ -731,6 +1090,15 @@ var DiffEditorManager = class {
731
1090
  clearTimeout(this.revealDebounceIdDiff);
732
1091
  this.revealDebounceIdDiff = null;
733
1092
  }
1093
+ if (this.revealIdleTimerIdDiff != null) {
1094
+ clearTimeout(this.revealIdleTimerIdDiff);
1095
+ this.revealIdleTimerIdDiff = null;
1096
+ }
1097
+ if (this.diffScrollWatcherSuppressionTimer != null) {
1098
+ clearTimeout(this.diffScrollWatcherSuppressionTimer);
1099
+ this.diffScrollWatcherSuppressionTimer = null;
1100
+ }
1101
+ this.revealTicketDiff = 0;
734
1102
  this.lastRevealLineDiff = null;
735
1103
  this.rafScheduler.cancel("content-size-change-diff");
736
1104
  this.rafScheduler.cancel("sync-last-known-modified");
@@ -744,7 +1112,7 @@ var DiffEditorManager = class {
744
1112
  this.lastKnownModifiedCode = model.getValue();
745
1113
  this.lastKnownModifiedLineCount = model.getLineCount();
746
1114
  }
747
- } catch {} finally {
1115
+ } finally {
748
1116
  this.lastKnownModifiedDirty = false;
749
1117
  }
750
1118
  }
@@ -788,10 +1156,20 @@ var DiffEditorManager = class {
788
1156
  else this.applyMinimalEditToModel(m, prevM, modified);
789
1157
  this.lastKnownModifiedCode = modified;
790
1158
  const newMLineCount = m.getLineCount();
791
- if (newMLineCount !== prevMLineCount) this.maybeScrollDiffToBottom(newMLineCount, prevMLineCount);
1159
+ if (newMLineCount !== prevMLineCount) {
1160
+ const shouldImmediate = this.shouldPerformImmediateRevealDiff();
1161
+ if (shouldImmediate) this.suppressScrollWatcherDiff(this.scrollWatcherSuppressionMs + 800);
1162
+ const computed$1 = this.computedHeight();
1163
+ if (computed$1 >= this.maxHeightValue - 1 && this.lastContainer) {
1164
+ this.lastContainer.style.height = `${this.maxHeightValue}px`;
1165
+ this.lastContainer.style.overflow = "auto";
1166
+ }
1167
+ if (shouldImmediate) this.scheduleImmediateRevealAfterLayoutDiff(newMLineCount);
1168
+ else this.maybeScrollDiffToBottom(newMLineCount, prevMLineCount);
1169
+ }
792
1170
  }
793
1171
  }
794
- flushAppendBufferDiff() {
1172
+ async flushAppendBufferDiff() {
795
1173
  if (!this.diffEditorView) return;
796
1174
  if (this.appendBufferDiff.length === 0) return;
797
1175
  this.appendBufferDiffScheduled = false;
@@ -801,39 +1179,128 @@ var DiffEditorManager = class {
801
1179
  this.appendBufferDiff.length = 0;
802
1180
  return;
803
1181
  }
804
- const text = this.appendBufferDiff.join("");
1182
+ let parts = this.appendBufferDiff.splice(0);
1183
+ const prevLineInit = model.getLineCount();
1184
+ const totalText = parts.join("");
1185
+ const totalChars = totalText.length;
1186
+ if (parts.length === 1 && totalChars > 5e3) {
1187
+ const lines = totalText.split(/\r?\n/);
1188
+ const chunkSize = 200;
1189
+ const chunks = [];
1190
+ for (let i = 0; i < lines.length; i += chunkSize) chunks.push(`${lines.slice(i, i + chunkSize).join("\n")}\n`);
1191
+ if (chunks.length > 1) parts = chunks;
1192
+ }
1193
+ const applyChunked = parts.length > 1 && (totalChars > 2e3 || model.getLineCount && model.getLineCount() + 0 - prevLineInit > 50);
1194
+ log("diff", "flushAppendBufferDiff start", {
1195
+ partsCount: parts.length,
1196
+ totalChars,
1197
+ applyChunked
1198
+ });
1199
+ let prevLine = prevLineInit;
1200
+ const watcherApi = this.diffScrollWatcher;
1201
+ let suppressedByFlush = false;
1202
+ if (watcherApi && typeof watcherApi.setSuppressed === "function") try {
1203
+ if (this.diffScrollWatcherSuppressionTimer != null) {
1204
+ clearTimeout(this.diffScrollWatcherSuppressionTimer);
1205
+ this.diffScrollWatcherSuppressionTimer = null;
1206
+ }
1207
+ watcherApi.setSuppressed(true);
1208
+ suppressedByFlush = true;
1209
+ } catch {}
1210
+ if (applyChunked) {
1211
+ log("diff", "flushAppendBufferDiff applying chunked", { partsLen: parts.length });
1212
+ let idx = 0;
1213
+ for (const part of parts) {
1214
+ if (!part) continue;
1215
+ idx += 1;
1216
+ log("diff", "flushAppendBufferDiff chunk", {
1217
+ idx,
1218
+ partLen: part.length,
1219
+ prevLine
1220
+ });
1221
+ const lastColumn$1 = model.getLineMaxColumn(prevLine);
1222
+ const range$1 = new monaco_shim_exports.Range(prevLine, lastColumn$1, prevLine, lastColumn$1);
1223
+ model.applyEdits([{
1224
+ range: range$1,
1225
+ text: part,
1226
+ forceMoveMarkers: true
1227
+ }]);
1228
+ this.lastKnownModifiedCode = model.getValue();
1229
+ const newLine$1 = model.getLineCount();
1230
+ this.lastKnownModifiedLineCount = newLine$1;
1231
+ await new Promise((resolve) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(resolve) : setTimeout(resolve, 0));
1232
+ const shouldImmediate$1 = this.shouldPerformImmediateRevealDiff();
1233
+ log("diff", "flushAppendBufferDiff chunk metrics", {
1234
+ idx,
1235
+ newLine: newLine$1,
1236
+ prevLine,
1237
+ shouldImmediate: shouldImmediate$1
1238
+ });
1239
+ if (shouldImmediate$1) this.suppressScrollWatcherDiff(this.scrollWatcherSuppressionMs + 800);
1240
+ const computed$2 = this.computedHeight();
1241
+ if (computed$2 >= this.maxHeightValue - 1 && this.lastContainer) {
1242
+ this.lastContainer.style.height = `${this.maxHeightValue}px`;
1243
+ this.lastContainer.style.overflow = "auto";
1244
+ }
1245
+ if (shouldImmediate$1) this.scheduleImmediateRevealAfterLayoutDiff(newLine$1);
1246
+ else this.maybeScrollDiffToBottom(newLine$1, prevLine);
1247
+ prevLine = newLine$1;
1248
+ log("diff", "flushAppendBufferDiff chunk applied", {
1249
+ idx,
1250
+ newLine: newLine$1
1251
+ });
1252
+ }
1253
+ if (suppressedByFlush) watcherApi.setSuppressed(false);
1254
+ return;
1255
+ }
1256
+ const text = totalText;
805
1257
  this.appendBufferDiff.length = 0;
1258
+ prevLine = model.getLineCount();
1259
+ const lastColumn = model.getLineMaxColumn(prevLine);
1260
+ const range = new monaco_shim_exports.Range(prevLine, lastColumn, prevLine, lastColumn);
1261
+ model.applyEdits([{
1262
+ range,
1263
+ text,
1264
+ forceMoveMarkers: true
1265
+ }]);
1266
+ this.lastKnownModifiedCode = model.getValue();
1267
+ const newLine = model.getLineCount();
1268
+ this.lastKnownModifiedLineCount = newLine;
1269
+ const shouldImmediate = this.shouldPerformImmediateRevealDiff();
1270
+ if (shouldImmediate) this.suppressScrollWatcherDiff(this.scrollWatcherSuppressionMs + 800);
1271
+ const computed$1 = this.computedHeight();
1272
+ if (computed$1 >= this.maxHeightValue - 1 && this.lastContainer) this.lastContainer.style.height = `${this.maxHeightValue}px`;
1273
+ if (shouldImmediate) this.scheduleImmediateRevealAfterLayoutDiff(newLine);
1274
+ else this.maybeScrollDiffToBottom(newLine, prevLine);
1275
+ if (this.autoScrollOnUpdate && this.shouldAutoScrollDiff) try {
1276
+ var _editor4, _me2$getModel2, _me2$getScrollTop2;
1277
+ const ScrollType = monaco_shim_exports.ScrollType || ((_editor4 = monaco_shim_exports.editor) === null || _editor4 === void 0 ? void 0 : _editor4.ScrollType);
1278
+ const immediate = ScrollType && typeof ScrollType.Immediate !== "undefined" ? ScrollType.Immediate : void 0;
1279
+ const me2 = this.diffEditorView.getModifiedEditor();
1280
+ const targetLine = ((_me2$getModel2 = me2.getModel()) === null || _me2$getModel2 === void 0 ? void 0 : _me2$getModel2.getLineCount()) ?? newLine;
1281
+ if (typeof immediate !== "undefined") me2.revealLine(targetLine, immediate);
1282
+ else me2.revealLine(targetLine);
1283
+ this.lastRevealLineDiff = targetLine;
1284
+ this.shouldAutoScrollDiff = true;
1285
+ this.lastScrollTopDiff = ((_me2$getScrollTop2 = me2.getScrollTop) === null || _me2$getScrollTop2 === void 0 ? void 0 : _me2$getScrollTop2.call(me2)) ?? this.lastScrollTopDiff;
1286
+ } catch {}
1287
+ if (suppressedByFlush) watcherApi.setSuppressed(false);
806
1288
  try {
807
- const prevLine = model.getLineCount();
808
- const lastColumn = model.getLineMaxColumn(prevLine);
809
- const range = new monaco_shim_exports.Range(prevLine, lastColumn, prevLine, lastColumn);
810
- model.applyEdits([{
811
- range,
812
- text,
813
- forceMoveMarkers: true
814
- }]);
815
- try {
816
- this.lastKnownModifiedCode = model.getValue();
817
- } catch {}
818
- const newLine = model.getLineCount();
819
- this.maybeScrollDiffToBottom(newLine, prevLine);
820
- this.lastKnownModifiedLineCount = newLine;
1289
+ var _this$diffEditorView5, _this$diffEditorView6, _this$diffEditorView7;
1290
+ this.shouldAutoScrollDiff = true;
1291
+ this.lastScrollTopDiff = ((_this$diffEditorView5 = this.diffEditorView) === null || _this$diffEditorView5 === void 0 || (_this$diffEditorView7 = (_this$diffEditorView6 = _this$diffEditorView5.getModifiedEditor()).getScrollTop) === null || _this$diffEditorView7 === void 0 ? void 0 : _this$diffEditorView7.call(_this$diffEditorView6)) ?? this.lastScrollTopDiff;
821
1292
  } catch {}
822
1293
  }
823
1294
  applyMinimalEditToModel(model, prev, next) {
824
- try {
825
- const maxChars = minimalEditMaxChars;
826
- const ratio = minimalEditMaxChangeRatio;
827
- const maxLen = Math.max(prev.length, next.length);
828
- const changeRatio = maxLen > 0 ? Math.abs(next.length - prev.length) / maxLen : 0;
829
- if (prev.length + next.length > maxChars || changeRatio > ratio) {
830
- model.setValue(next);
831
- try {
832
- if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
833
- } catch {}
834
- return;
835
- }
836
- } catch {}
1295
+ const maxChars = minimalEditMaxChars;
1296
+ const ratio = minimalEditMaxChangeRatio;
1297
+ const maxLen = Math.max(prev.length, next.length);
1298
+ const changeRatio = maxLen > 0 ? Math.abs(next.length - prev.length) / maxLen : 0;
1299
+ if (prev.length + next.length > maxChars || changeRatio > ratio) {
1300
+ model.setValue(next);
1301
+ if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
1302
+ return;
1303
+ }
837
1304
  const res = computeMinimalEdit(prev, next);
838
1305
  if (!res) return;
839
1306
  const { start, endPrevIncl, replaceText } = res;
@@ -845,9 +1312,7 @@ var DiffEditorManager = class {
845
1312
  text: replaceText,
846
1313
  forceMoveMarkers: true
847
1314
  }]);
848
- try {
849
- if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
850
- } catch {}
1315
+ if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
851
1316
  }
852
1317
  appendToModel(model, appendText) {
853
1318
  if (!appendText) return;
@@ -859,9 +1324,7 @@ var DiffEditorManager = class {
859
1324
  text: appendText,
860
1325
  forceMoveMarkers: true
861
1326
  }]);
862
- try {
863
- if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
864
- } catch {}
1327
+ if (model === this.modifiedModel) this.lastKnownModifiedLineCount = model.getLineCount();
865
1328
  }
866
1329
  };
867
1330
 
@@ -875,12 +1338,14 @@ var EditorManager = class {
875
1338
  _hasScrollBar = false;
876
1339
  shouldAutoScroll = true;
877
1340
  scrollWatcher = null;
1341
+ scrollWatcherSuppressionTimer = null;
878
1342
  lastScrollTop = 0;
879
1343
  cachedScrollHeight = null;
880
1344
  cachedLineHeight = null;
881
1345
  cachedComputedHeight = null;
882
1346
  cachedLineCount = null;
883
1347
  lastKnownCodeDirty = false;
1348
+ debug = false;
884
1349
  measureViewport() {
885
1350
  var _this$editorView$getL, _this$editorView, _this$editorView$getS, _this$editorView2, _this$editorView$getS2, _this$editorView3;
886
1351
  if (!this.editorView) return null;
@@ -908,8 +1373,10 @@ var EditorManager = class {
908
1373
  revealDebounceId = null;
909
1374
  revealDebounceMs = defaultRevealDebounceMs;
910
1375
  revealIdleTimerId = null;
1376
+ revealTicket = 0;
911
1377
  revealStrategyOption;
912
1378
  revealBatchOnIdleMsOption;
1379
+ scrollWatcherSuppressionMs = 500;
913
1380
  constructor(options, maxHeightValue, maxHeightCSS, autoScrollOnUpdate, autoScrollInitial, autoScrollThresholdPx, autoScrollThresholdLines, revealDebounceMsOption) {
914
1381
  this.options = options;
915
1382
  this.maxHeightValue = maxHeightValue;
@@ -920,6 +1387,21 @@ var EditorManager = class {
920
1387
  this.autoScrollThresholdLines = autoScrollThresholdLines;
921
1388
  this.revealDebounceMsOption = revealDebounceMsOption;
922
1389
  }
1390
+ initDebugFlag() {
1391
+ if (typeof window !== "undefined" && window.__STREAM_MONACO_DEBUG__ !== void 0) {
1392
+ this.debug = Boolean(window.__STREAM_MONACO_DEBUG__);
1393
+ return;
1394
+ }
1395
+ if (this.options && this.options.debug !== void 0) {
1396
+ this.debug = Boolean(this.options.debug);
1397
+ return;
1398
+ }
1399
+ this.debug = false;
1400
+ }
1401
+ dlog(...args) {
1402
+ if (!this.debug) return;
1403
+ log("EditorManager", ...args);
1404
+ }
923
1405
  hasVerticalScrollbar() {
924
1406
  if (!this.editorView) return false;
925
1407
  if (this._hasScrollBar) return true;
@@ -941,19 +1423,38 @@ var EditorManager = class {
941
1423
  const lineCount = this.cachedLineCount ?? ((_editorView$getModel = editorView.getModel()) === null || _editorView$getModel === void 0 ? void 0 : _editorView$getModel.getLineCount()) ?? 1;
942
1424
  const lineHeight = editorView.getOption(monaco_shim_exports.editor.EditorOption.lineHeight);
943
1425
  const height = Math.min(lineCount * lineHeight + padding, this.maxHeightValue);
1426
+ log("EditorManager.computedHeight", {
1427
+ lineCount,
1428
+ lineHeight,
1429
+ computed: height,
1430
+ maxHeightValue: this.maxHeightValue
1431
+ });
944
1432
  return height;
945
1433
  }
946
1434
  maybeScrollToBottom(targetLine) {
947
1435
  this.rafScheduler.schedule("maybe-scroll", () => {
948
- if (!(this.autoScrollOnUpdate && this.shouldAutoScroll && this.hasVerticalScrollbar())) return;
1436
+ const hasVS = this.hasVerticalScrollbar();
1437
+ this.dlog("maybeScrollToBottom called", {
1438
+ autoScrollOnUpdate: this.autoScrollOnUpdate,
1439
+ shouldAutoScroll: this.shouldAutoScroll,
1440
+ hasVerticalScrollbar: hasVS,
1441
+ targetLine
1442
+ });
1443
+ if (!(this.autoScrollOnUpdate && this.shouldAutoScroll && this.hasVerticalScrollbar())) {
1444
+ this.dlog("maybeScrollToBottom skipped (auto-scroll conditions not met)");
1445
+ return;
1446
+ }
949
1447
  const model = this.editorView.getModel();
950
1448
  const line = targetLine ?? (model === null || model === void 0 ? void 0 : model.getLineCount()) ?? 1;
951
1449
  const batchMs = this.revealBatchOnIdleMsOption ?? this.options.revealBatchOnIdleMs ?? defaultRevealBatchOnIdleMs;
952
1450
  if (typeof batchMs === "number" && batchMs > 0) {
953
1451
  if (this.revealIdleTimerId != null) clearTimeout(this.revealIdleTimerId);
1452
+ const ticket = ++this.revealTicket;
1453
+ this.dlog("scheduled idle reveal ticket=", ticket, "line=", line, "batchMs=", batchMs);
954
1454
  this.revealIdleTimerId = setTimeout(() => {
955
1455
  this.revealIdleTimerId = null;
956
- this.performReveal(line);
1456
+ this.dlog("idle reveal timer firing, ticket=", ticket, "line=", line);
1457
+ this.performReveal(line, ticket);
957
1458
  }, batchMs);
958
1459
  return;
959
1460
  }
@@ -964,14 +1465,22 @@ var EditorManager = class {
964
1465
  const ms = typeof this.revealDebounceMs === "number" && this.revealDebounceMs > 0 ? this.revealDebounceMs : typeof this.revealDebounceMsOption === "number" && this.revealDebounceMsOption > 0 ? this.revealDebounceMsOption : this.revealDebounceMs;
965
1466
  this.revealDebounceId = setTimeout(() => {
966
1467
  this.revealDebounceId = null;
967
- this.performReveal(line);
1468
+ const ticket = ++this.revealTicket;
1469
+ this.dlog("scheduled debounce reveal ticket=", ticket, "line=", line, "ms=", ms);
1470
+ this.performReveal(line, ticket);
968
1471
  }, ms);
969
1472
  });
970
1473
  }
971
- performReveal(line) {
1474
+ performReveal(line, ticket) {
972
1475
  this.rafScheduler.schedule("reveal", () => {
973
1476
  var _editor;
1477
+ if (ticket !== this.revealTicket) {
1478
+ this.dlog("performReveal skipped, stale ticket", ticket, "current", this.revealTicket);
1479
+ return;
1480
+ }
1481
+ this.dlog("performReveal executing, ticket=", ticket, "line=", line);
974
1482
  const strategy = this.revealStrategyOption ?? this.options.revealStrategy ?? "centerIfOutside";
1483
+ this.dlog("performReveal strategy=", strategy);
975
1484
  const ScrollType = monaco_shim_exports.ScrollType || ((_editor = monaco_shim_exports.editor) === null || _editor === void 0 ? void 0 : _editor.ScrollType);
976
1485
  const smooth = ScrollType && typeof ScrollType.Smooth !== "undefined" ? ScrollType.Smooth : void 0;
977
1486
  try {
@@ -988,11 +1497,59 @@ var EditorManager = class {
988
1497
  }
989
1498
  });
990
1499
  }
1500
+ performImmediateReveal(line, ticket) {
1501
+ this.dlog("performImmediateReveal line=", line, "ticket=", ticket);
1502
+ try {
1503
+ var _editor2;
1504
+ if (!this.editorView) return;
1505
+ if (ticket !== this.revealTicket) {
1506
+ this.dlog("performImmediateReveal skipped, stale ticket", ticket, "current", this.revealTicket);
1507
+ return;
1508
+ }
1509
+ const ScrollType = monaco_shim_exports.ScrollType || ((_editor2 = monaco_shim_exports.editor) === null || _editor2 === void 0 ? void 0 : _editor2.ScrollType);
1510
+ const immediate = ScrollType && typeof ScrollType.Immediate !== "undefined" ? ScrollType.Immediate : void 0;
1511
+ if (typeof immediate !== "undefined") this.editorView.revealLine(line, immediate);
1512
+ else this.editorView.revealLine(line);
1513
+ } catch {}
1514
+ try {
1515
+ this.measureViewport();
1516
+ } catch {}
1517
+ }
1518
+ forceReveal(line) {
1519
+ try {
1520
+ var _editor3;
1521
+ if (!this.editorView) return;
1522
+ const ScrollType = monaco_shim_exports.ScrollType || ((_editor3 = monaco_shim_exports.editor) === null || _editor3 === void 0 ? void 0 : _editor3.ScrollType);
1523
+ const immediate = ScrollType && typeof ScrollType.Immediate !== "undefined" ? ScrollType.Immediate : void 0;
1524
+ if (typeof immediate !== "undefined") this.editorView.revealLine(line, immediate);
1525
+ else this.editorView.revealLine(line);
1526
+ } catch {}
1527
+ try {
1528
+ this.measureViewport();
1529
+ } catch {}
1530
+ try {
1531
+ var _this$editorView4, _this$editorView4$get;
1532
+ this.shouldAutoScroll = true;
1533
+ this.lastScrollTop = ((_this$editorView4 = this.editorView) === null || _this$editorView4 === void 0 || (_this$editorView4$get = _this$editorView4.getScrollTop) === null || _this$editorView4$get === void 0 ? void 0 : _this$editorView4$get.call(_this$editorView4)) ?? this.lastScrollTop;
1534
+ } catch {}
1535
+ }
1536
+ isOverflowAuto() {
1537
+ try {
1538
+ return !!this.lastContainer && this.lastContainer.style.overflow === "auto";
1539
+ } catch {
1540
+ return false;
1541
+ }
1542
+ }
1543
+ shouldPerformImmediateReveal() {
1544
+ return this.autoScrollOnUpdate && this.shouldAutoScroll && this.hasVerticalScrollbar() && this.isOverflowAuto();
1545
+ }
991
1546
  async createEditor(container, code, language, currentTheme) {
992
- var _this$editorView$getS3, _this$editorView4, _this$editorView$getO, _this$editorView5, _this$editorView$getM, _this$editorView$onDi, _this$editorView6;
1547
+ var _this$editorView$getS3, _this$editorView5, _this$editorView$getO, _this$editorView6, _this$editorView$getM, _this$editorView$onDi, _this$editorView7;
993
1548
  this.cleanup();
994
1549
  this.lastContainer = container;
995
- container.style.overflow = "auto";
1550
+ this.initDebugFlag();
1551
+ this.dlog("createEditor container, maxHeight", this.maxHeightValue);
1552
+ container.style.overflow = "hidden";
996
1553
  container.style.maxHeight = this.maxHeightCSS;
997
1554
  this.editorView = monaco_shim_exports.editor.create(container, {
998
1555
  value: code,
@@ -1023,22 +1580,51 @@ var EditorManager = class {
1023
1580
  }
1024
1581
  if (this.revealIdleTimerId != null) clearTimeout(this.revealIdleTimerId);
1025
1582
  this.revealIdleTimerId = null;
1026
- this.editorHeightManager = createHeightManager(container, () => this.computedHeight(this.editorView));
1583
+ const MIN_VISIBLE_HEIGHT = Math.min(120, this.maxHeightValue);
1584
+ container.style.minHeight = `${MIN_VISIBLE_HEIGHT}px`;
1585
+ this.editorHeightManager = createHeightManager(container, () => {
1586
+ const computed$1 = this.computedHeight(this.editorView);
1587
+ const clamped = Math.min(computed$1, this.maxHeightValue);
1588
+ return Math.max(clamped, MIN_VISIBLE_HEIGHT);
1589
+ });
1027
1590
  this.editorHeightManager.update();
1028
- this.cachedScrollHeight = ((_this$editorView$getS3 = (_this$editorView4 = this.editorView).getScrollHeight) === null || _this$editorView$getS3 === void 0 ? void 0 : _this$editorView$getS3.call(_this$editorView4)) ?? null;
1029
- this.cachedLineHeight = ((_this$editorView$getO = (_this$editorView5 = this.editorView).getOption) === null || _this$editorView$getO === void 0 ? void 0 : _this$editorView$getO.call(_this$editorView5, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? null;
1591
+ const initialComputed = this.computedHeight(this.editorView);
1592
+ if (initialComputed >= this.maxHeightValue - 1) {
1593
+ container.style.height = `${this.maxHeightValue}px`;
1594
+ container.style.overflow = "auto";
1595
+ this.dlog("applied immediate maxHeight on createEditor", this.maxHeightValue);
1596
+ }
1597
+ this.cachedScrollHeight = ((_this$editorView$getS3 = (_this$editorView5 = this.editorView).getScrollHeight) === null || _this$editorView$getS3 === void 0 ? void 0 : _this$editorView$getS3.call(_this$editorView5)) ?? null;
1598
+ this.cachedLineHeight = ((_this$editorView$getO = (_this$editorView6 = this.editorView).getOption) === null || _this$editorView$getO === void 0 ? void 0 : _this$editorView$getO.call(_this$editorView6, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? null;
1030
1599
  this.cachedComputedHeight = this.computedHeight(this.editorView);
1031
1600
  this.cachedLineCount = ((_this$editorView$getM = this.editorView.getModel()) === null || _this$editorView$getM === void 0 ? void 0 : _this$editorView$getM.getLineCount()) ?? null;
1032
- (_this$editorView$onDi = (_this$editorView6 = this.editorView).onDidContentSizeChange) === null || _this$editorView$onDi === void 0 || _this$editorView$onDi.call(_this$editorView6, () => {
1601
+ (_this$editorView$onDi = (_this$editorView7 = this.editorView).onDidContentSizeChange) === null || _this$editorView$onDi === void 0 || _this$editorView$onDi.call(_this$editorView7, () => {
1033
1602
  this._hasScrollBar = false;
1034
1603
  this.rafScheduler.schedule("content-size-change", () => {
1035
1604
  try {
1036
- var _this$editorView7, _this$editorHeightMan, _this$editorHeightMan2;
1037
- this.measureViewport();
1038
- this.cachedLineCount = ((_this$editorView7 = this.editorView) === null || _this$editorView7 === void 0 || (_this$editorView7 = _this$editorView7.getModel()) === null || _this$editorView7 === void 0 ? void 0 : _this$editorView7.getLineCount()) ?? this.cachedLineCount;
1039
- if ((_this$editorHeightMan = this.editorHeightManager) === null || _this$editorHeightMan === void 0 ? void 0 : _this$editorHeightMan.isSuppressed()) return;
1605
+ var _this$editorView8, _this$editorHeightMan, _this$editorHeightMan2;
1606
+ this.dlog("content-size-change frame");
1607
+ const m = this.measureViewport();
1608
+ this.dlog("content-size-change measure", m);
1609
+ this.cachedLineCount = ((_this$editorView8 = this.editorView) === null || _this$editorView8 === void 0 || (_this$editorView8 = _this$editorView8.getModel()) === null || _this$editorView8 === void 0 ? void 0 : _this$editorView8.getLineCount()) ?? this.cachedLineCount;
1610
+ if ((_this$editorHeightMan = this.editorHeightManager) === null || _this$editorHeightMan === void 0 ? void 0 : _this$editorHeightMan.isSuppressed()) {
1611
+ this.dlog("content-size-change skipped height update (suppressed)");
1612
+ return;
1613
+ }
1614
+ this.dlog("content-size-change calling heightManager.update");
1040
1615
  (_this$editorHeightMan2 = this.editorHeightManager) === null || _this$editorHeightMan2 === void 0 || _this$editorHeightMan2.update();
1041
- } catch {}
1616
+ const computed$1 = this.computedHeight(this.editorView);
1617
+ if (this.lastContainer) {
1618
+ const prevOverflow = this.lastContainer.style.overflow;
1619
+ const newOverflow = computed$1 >= this.maxHeightValue - 1 ? "auto" : "hidden";
1620
+ if (prevOverflow !== newOverflow) {
1621
+ this.lastContainer.style.overflow = newOverflow;
1622
+ if (newOverflow === "auto" && this.shouldAutoScroll) this.maybeScrollToBottom();
1623
+ }
1624
+ }
1625
+ } catch (err) {
1626
+ error("EditorManager", "content-size-change error", err);
1627
+ }
1042
1628
  });
1043
1629
  });
1044
1630
  this.editorView.onDidChangeModelContent(() => {
@@ -1069,15 +1655,67 @@ var EditorManager = class {
1069
1655
  }
1070
1656
  syncLastKnownCode() {
1071
1657
  if (!this.editorView || !this.lastKnownCodeDirty) return;
1072
- try {
1073
- const model = this.editorView.getModel();
1074
- if (model) {
1075
- this.lastKnownCode = model.getValue();
1076
- this.cachedLineCount = model.getLineCount() ?? this.cachedLineCount;
1658
+ const model = this.editorView.getModel();
1659
+ if (model) {
1660
+ this.lastKnownCode = model.getValue();
1661
+ this.cachedLineCount = model.getLineCount() ?? this.cachedLineCount;
1662
+ }
1663
+ this.lastKnownCodeDirty = false;
1664
+ }
1665
+ suppressScrollWatcher(ms) {
1666
+ if (!this.scrollWatcher || typeof this.scrollWatcher.setSuppressed !== "function") return;
1667
+ this.dlog("suppressScrollWatcher", ms);
1668
+ if (this.scrollWatcherSuppressionTimer != null) {
1669
+ clearTimeout(this.scrollWatcherSuppressionTimer);
1670
+ this.scrollWatcherSuppressionTimer = null;
1671
+ }
1672
+ this.scrollWatcher.setSuppressed(true);
1673
+ this.scrollWatcherSuppressionTimer = setTimeout(() => {
1674
+ if (this.scrollWatcher && typeof this.scrollWatcher.setSuppressed === "function") {
1675
+ this.scrollWatcher.setSuppressed(false);
1676
+ this.dlog("suppressScrollWatcher cleared");
1077
1677
  }
1078
- } catch {} finally {
1079
- this.lastKnownCodeDirty = false;
1080
- }
1678
+ this.scrollWatcherSuppressionTimer = null;
1679
+ }, ms);
1680
+ }
1681
+ scheduleImmediateRevealAfterLayout(line) {
1682
+ const ticket = ++this.revealTicket;
1683
+ this.dlog("scheduleImmediateRevealAfterLayout ticket=", ticket, "line=", line);
1684
+ this.rafScheduler.schedule("immediate-reveal", async () => {
1685
+ try {
1686
+ const target = this.editorView && this.editorHeightManager ? Math.min(this.computedHeight(this.editorView), this.maxHeightValue) : -1;
1687
+ if (target !== -1 && this.editorHeightManager) await this.waitForHeightApplied(target, 500);
1688
+ else await new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(() => r())));
1689
+ this.dlog("running delayed immediate reveal", "ticket=", ticket, "line=", line);
1690
+ this.performImmediateReveal(line, ticket);
1691
+ } catch (err) {
1692
+ error("EditorManager", "scheduleImmediateRevealAfterLayout error", err);
1693
+ }
1694
+ });
1695
+ }
1696
+ waitForHeightApplied(target, timeoutMs = 500) {
1697
+ return new Promise((resolve) => {
1698
+ const start = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
1699
+ const check = () => {
1700
+ try {
1701
+ var _this$editorHeightMan3, _this$editorHeightMan4;
1702
+ const last = ((_this$editorHeightMan3 = this.editorHeightManager) === null || _this$editorHeightMan3 === void 0 || (_this$editorHeightMan4 = _this$editorHeightMan3.getLastApplied) === null || _this$editorHeightMan4 === void 0 ? void 0 : _this$editorHeightMan4.call(_this$editorHeightMan3)) ?? -1;
1703
+ if (last !== -1 && Math.abs(last - target) <= 12) {
1704
+ this.dlog("waitForHeightApplied satisfied", last, "target=", target);
1705
+ resolve();
1706
+ return;
1707
+ }
1708
+ const now = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
1709
+ if (now - start > timeoutMs) {
1710
+ log("EditorManager", "waitForHeightApplied timeout", last, "target=", target);
1711
+ resolve();
1712
+ return;
1713
+ }
1714
+ } catch {}
1715
+ requestAnimationFrame(check);
1716
+ };
1717
+ check();
1718
+ });
1081
1719
  }
1082
1720
  updateCode(newCode, codeLanguage) {
1083
1721
  this.pendingUpdate = {
@@ -1101,7 +1739,13 @@ var EditorManager = class {
1101
1739
  this.lastKnownCode = newCode;
1102
1740
  const newLineCount$1 = model.getLineCount();
1103
1741
  this.cachedLineCount = newLineCount$1;
1104
- if (newLineCount$1 !== prevLineCount$1) this.maybeScrollToBottom(newLineCount$1);
1742
+ if (newLineCount$1 !== prevLineCount$1) {
1743
+ const shouldImmediate = this.shouldPerformImmediateReveal();
1744
+ if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
1745
+ const computed$1 = this.computedHeight(this.editorView);
1746
+ if (computed$1 >= this.maxHeightValue - 1 && this.lastContainer) this.lastContainer.style.height = `${this.maxHeightValue}px`;
1747
+ this.forceReveal(newLineCount$1);
1748
+ }
1105
1749
  return;
1106
1750
  }
1107
1751
  const prevCode = this.appendBuffer.length > 0 ? this.editorView.getValue() : this.lastKnownCode ?? this.editorView.getValue();
@@ -1117,7 +1761,12 @@ var EditorManager = class {
1117
1761
  this.lastKnownCode = newCode;
1118
1762
  const newLineCount = model.getLineCount();
1119
1763
  this.cachedLineCount = newLineCount;
1120
- if (newLineCount !== prevLineCount) this.maybeScrollToBottom(newLineCount);
1764
+ if (newLineCount !== prevLineCount) {
1765
+ const shouldImmediate = this.shouldPerformImmediateReveal();
1766
+ if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
1767
+ if (shouldImmediate) this.scheduleImmediateRevealAfterLayout(newLineCount);
1768
+ else this.maybeScrollToBottom(newLineCount);
1769
+ }
1121
1770
  }
1122
1771
  appendCode(appendText, codeLanguage) {
1123
1772
  if (!this.editorView) return;
@@ -1137,21 +1786,19 @@ var EditorManager = class {
1137
1786
  if (!this.editorView) return;
1138
1787
  const model = this.editorView.getModel();
1139
1788
  if (!model) return;
1140
- try {
1141
- const maxChars = minimalEditMaxChars;
1142
- const ratio = minimalEditMaxChangeRatio;
1143
- const maxLen = Math.max(prev.length, next.length);
1144
- const changeRatio = maxLen > 0 ? Math.abs(next.length - prev.length) / maxLen : 0;
1145
- if (prev.length + next.length > maxChars || changeRatio > ratio) {
1146
- const prevLineCount = model.getLineCount();
1147
- model.setValue(next);
1148
- this.lastKnownCode = next;
1149
- const newLineCount = model.getLineCount();
1150
- this.cachedLineCount = newLineCount;
1151
- if (newLineCount !== prevLineCount) this.maybeScrollToBottom(newLineCount);
1152
- return;
1153
- }
1154
- } catch {}
1789
+ const maxChars = minimalEditMaxChars;
1790
+ const ratio = minimalEditMaxChangeRatio;
1791
+ const maxLen = Math.max(prev.length, next.length);
1792
+ const changeRatio = maxLen > 0 ? Math.abs(next.length - prev.length) / maxLen : 0;
1793
+ if (prev.length + next.length > maxChars || changeRatio > ratio) {
1794
+ const prevLineCount = model.getLineCount();
1795
+ model.setValue(next);
1796
+ this.lastKnownCode = next;
1797
+ const newLineCount = model.getLineCount();
1798
+ this.cachedLineCount = newLineCount;
1799
+ if (newLineCount !== prevLineCount) this.maybeScrollToBottom(newLineCount);
1800
+ return;
1801
+ }
1155
1802
  const res = computeMinimalEdit(prev, next);
1156
1803
  if (!res) return;
1157
1804
  const { start, endPrevIncl, replaceText } = res;
@@ -1195,7 +1842,14 @@ var EditorManager = class {
1195
1842
  const newLineCount = model.getLineCount();
1196
1843
  if (lastLine !== newLineCount) {
1197
1844
  this.cachedLineCount = newLineCount;
1198
- this.maybeScrollToBottom(newLineCount);
1845
+ const shouldImmediate = this.shouldPerformImmediateReveal();
1846
+ if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
1847
+ const computed$1 = this.computedHeight(this.editorView);
1848
+ if (computed$1 >= this.maxHeightValue - 1 && this.lastContainer) this.lastContainer.style.height = `${this.maxHeightValue}px`;
1849
+ if (shouldImmediate) try {
1850
+ this.forceReveal(newLineCount);
1851
+ } catch {}
1852
+ else this.maybeScrollToBottom(newLineCount);
1199
1853
  }
1200
1854
  }
1201
1855
  setLanguage(language, languages$1) {
@@ -1213,16 +1867,33 @@ var EditorManager = class {
1213
1867
  this.rafScheduler.cancel("update");
1214
1868
  this.rafScheduler.cancel("sync-last-known");
1215
1869
  this.rafScheduler.cancel("content-size-change");
1870
+ this.rafScheduler.cancel("maybe-scroll");
1871
+ this.rafScheduler.cancel("reveal");
1872
+ this.rafScheduler.cancel("immediate-reveal");
1873
+ this.rafScheduler.cancel("maybe-resume");
1216
1874
  this.pendingUpdate = null;
1217
1875
  this.rafScheduler.cancel("append");
1218
1876
  this.appendBufferScheduled = false;
1219
1877
  this.appendBuffer.length = 0;
1878
+ if (this.revealDebounceId != null) {
1879
+ clearTimeout(this.revealDebounceId);
1880
+ this.revealDebounceId = null;
1881
+ }
1882
+ if (this.revealIdleTimerId != null) {
1883
+ clearTimeout(this.revealIdleTimerId);
1884
+ this.revealIdleTimerId = null;
1885
+ }
1886
+ if (this.scrollWatcherSuppressionTimer != null) {
1887
+ clearTimeout(this.scrollWatcherSuppressionTimer);
1888
+ this.scrollWatcherSuppressionTimer = null;
1889
+ }
1220
1890
  if (this.editorView) {
1221
1891
  this.editorView.dispose();
1222
1892
  this.editorView = null;
1223
1893
  }
1224
1894
  this.lastKnownCode = null;
1225
1895
  if (this.lastContainer) {
1896
+ this.lastContainer.style.minHeight = "";
1226
1897
  this.lastContainer.innerHTML = "";
1227
1898
  this.lastContainer = null;
1228
1899
  }
@@ -1240,13 +1911,27 @@ var EditorManager = class {
1240
1911
  this.pendingUpdate = null;
1241
1912
  this.rafScheduler.cancel("sync-last-known");
1242
1913
  if (this.scrollWatcher) {
1243
- this.scrollWatcher.dispose();
1914
+ try {
1915
+ this.scrollWatcher.dispose();
1916
+ } catch {}
1244
1917
  this.scrollWatcher = null;
1245
1918
  }
1246
1919
  if (this.revealDebounceId != null) {
1247
1920
  clearTimeout(this.revealDebounceId);
1248
1921
  this.revealDebounceId = null;
1249
1922
  }
1923
+ if (this.revealIdleTimerId != null) {
1924
+ clearTimeout(this.revealIdleTimerId);
1925
+ this.revealIdleTimerId = null;
1926
+ }
1927
+ if (this.scrollWatcherSuppressionTimer != null) {
1928
+ clearTimeout(this.scrollWatcherSuppressionTimer);
1929
+ this.scrollWatcherSuppressionTimer = null;
1930
+ }
1931
+ this.rafScheduler.cancel("maybe-scroll");
1932
+ this.rafScheduler.cancel("reveal");
1933
+ this.rafScheduler.cancel("immediate-reveal");
1934
+ this.rafScheduler.cancel("maybe-resume");
1250
1935
  this._hasScrollBar = false;
1251
1936
  this.shouldAutoScroll = !!this.autoScrollInitial;
1252
1937
  this.lastScrollTop = 0;
@@ -1553,6 +2238,7 @@ let RevealStrategy = /* @__PURE__ */ function(RevealStrategy$1) {
1553
2238
  * getEditorView: () => monaco.editor.IStandaloneCodeEditor | null,
1554
2239
  * getDiffEditorView: () => monaco.editor.IStandaloneDiffEditor | null,
1555
2240
  * getDiffModels: () => { original: monaco.editor.ITextModel | null, modified: monaco.editor.ITextModel | null },
2241
+ * getCode: () => string | { original: string, modified: string } | null,
1556
2242
  * }} 返回对象包含以下方法和属性:
1557
2243
  *
1558
2244
  * @property {Function} createEditor - 创建并挂载 Monaco 编辑器到指定容器
@@ -1572,6 +2258,7 @@ let RevealStrategy = /* @__PURE__ */ function(RevealStrategy$1) {
1572
2258
  * @property {Function} getEditorView - 获取当前编辑器实例
1573
2259
  * @property {Function} getDiffEditorView - 获取当前 Diff 编辑器实例
1574
2260
  * @property {Function} getDiffModels - 获取 Diff 的 original/modified 两个模型
2261
+ * @property {Function} getCode - 获取当前编辑器或 Diff 编辑器中的代码内容
1575
2262
  *
1576
2263
  * @throws {Error} 当主题数组不是数组或长度小于2时抛出错误
1577
2264
  *
@@ -1732,9 +2419,7 @@ function useMonaco(monacoOptions = {}) {
1732
2419
  flush: "post",
1733
2420
  immediate: true
1734
2421
  });
1735
- try {
1736
- if (editorView) lastKnownCode = editorView.getValue();
1737
- } catch {}
2422
+ if (editorView) lastKnownCode = editorView.getValue();
1738
2423
  return editorView;
1739
2424
  }
1740
2425
  function computedHeight(editorView$1) {
@@ -2078,7 +2763,26 @@ function useMonaco(monacoOptions = {}) {
2078
2763
  return monaco_shim_exports;
2079
2764
  },
2080
2765
  setUpdateThrottleMs,
2081
- getUpdateThrottleMs
2766
+ getUpdateThrottleMs,
2767
+ getCode() {
2768
+ if (editorView) try {
2769
+ var _editorView$getModel;
2770
+ return ((_editorView$getModel = editorView.getModel()) === null || _editorView$getModel === void 0 ? void 0 : _editorView$getModel.getValue()) ?? null;
2771
+ } catch {
2772
+ return null;
2773
+ }
2774
+ if (diffEditorView || originalModel && modifiedModel) try {
2775
+ const original = (originalModel === null || originalModel === void 0 ? void 0 : originalModel.getValue()) ?? "";
2776
+ const modified = (modifiedModel === null || modifiedModel === void 0 ? void 0 : modifiedModel.getValue()) ?? "";
2777
+ return {
2778
+ original,
2779
+ modified
2780
+ };
2781
+ } catch {
2782
+ return null;
2783
+ }
2784
+ return null;
2785
+ }
2082
2786
  };
2083
2787
  }
2084
2788