stream-monaco 0.0.39 → 0.0.41

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.
@@ -264,32 +264,45 @@ function error(tag, ...args) {
264
264
 
265
265
  //#endregion
266
266
  //#region src/utils/height.ts
267
- function createHeightManager(container, computeNext) {
267
+ const DEFAULT_TRANSITION_MS = 120;
268
+ const DEFAULT_TRANSITION_EASING = "cubic-bezier(0.4, 0, 0.2, 1)";
269
+ const DEFAULT_HYSTERESIS_PX = 12;
270
+ const DEFAULT_DEBOUNCE_MS = 0;
271
+ function prefersReducedMotion() {
272
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
273
+ }
274
+ function createHeightManager(container, computeNext, options = {}) {
275
+ const transitionMs = Math.max(0, options.transitionMs ?? DEFAULT_TRANSITION_MS);
276
+ const transitionEasing = options.transitionEasing ?? DEFAULT_TRANSITION_EASING;
277
+ const hysteresisPx = Math.max(0, options.hysteresisPx ?? DEFAULT_HYSTERESIS_PX);
278
+ const debounceMs = Math.max(0, options.debounceMs ?? DEFAULT_DEBOUNCE_MS);
279
+ const transitionEnabled = options.smooth === true && transitionMs > 0 && !prefersReducedMotion();
280
+ const previousTransition = container.style.transition || "";
281
+ const heightTransition = `height ${transitionMs}ms ${transitionEasing}`;
282
+ if (transitionEnabled) container.style.transition = previousTransition ? `${previousTransition}, ${heightTransition}` : heightTransition;
268
283
  let raf = null;
269
284
  let debounceTimer = null;
270
285
  let lastApplied = -1;
271
286
  let suppressed = false;
272
- const HYSTERESIS_PX = 12;
273
- const DEBOUNCE_MS = 0;
274
287
  function apply() {
275
288
  var _container$getBoundin;
276
289
  const next = computeNext();
277
- if (next == null) return;
290
+ if (next == null) return null;
278
291
  log("heightManager", "computeNext ->", {
279
292
  next,
280
293
  lastApplied
281
294
  });
282
295
  if (!Number.isFinite(next) || next <= 0) {
283
296
  log("heightManager", "invalid next height, ignoring", next);
284
- return;
297
+ return null;
285
298
  }
286
299
  const currentHeight = Number.parseFloat(container.style.height || "") || ((_container$getBoundin = container.getBoundingClientRect) === null || _container$getBoundin === void 0 ? void 0 : _container$getBoundin.call(container).height) || 0;
287
- if (currentHeight > 0 && Math.abs(next - currentHeight) <= HYSTERESIS_PX) {
300
+ if (currentHeight > 0 && Math.abs(next - currentHeight) <= hysteresisPx) {
288
301
  lastApplied = next;
289
- return;
302
+ return next;
290
303
  }
291
- if (lastApplied !== -1 && Math.abs(next - lastApplied) <= HYSTERESIS_PX) return;
292
- if (next === lastApplied) return;
304
+ if (lastApplied !== -1 && Math.abs(next - lastApplied) <= hysteresisPx) return next;
305
+ if (next === lastApplied) return next;
293
306
  suppressed = true;
294
307
  container.style.height = `${next}px`;
295
308
  lastApplied = next;
@@ -297,13 +310,14 @@ function createHeightManager(container, computeNext) {
297
310
  queueMicrotask(() => {
298
311
  suppressed = false;
299
312
  });
313
+ return next;
300
314
  }
301
315
  function scheduleApply() {
302
316
  if (debounceTimer != null) {
303
317
  clearTimeout(debounceTimer);
304
318
  debounceTimer = null;
305
319
  }
306
- if (DEBOUNCE_MS === 0) {
320
+ if (debounceMs === 0) {
307
321
  if (raf != null) return;
308
322
  raf = requestAnimationFrame(() => {
309
323
  raf = null;
@@ -318,11 +332,22 @@ function createHeightManager(container, computeNext) {
318
332
  raf = null;
319
333
  apply();
320
334
  });
321
- }, DEBOUNCE_MS);
335
+ }, debounceMs);
322
336
  }
323
337
  function update() {
324
338
  scheduleApply();
325
339
  }
340
+ function updateNow() {
341
+ if (raf != null) {
342
+ cancelAnimationFrame(raf);
343
+ raf = null;
344
+ }
345
+ if (debounceTimer != null) {
346
+ clearTimeout(debounceTimer);
347
+ debounceTimer = null;
348
+ }
349
+ return apply();
350
+ }
326
351
  function dispose() {
327
352
  if (raf != null) {
328
353
  cancelAnimationFrame(raf);
@@ -332,6 +357,10 @@ function createHeightManager(container, computeNext) {
332
357
  clearTimeout(debounceTimer);
333
358
  debounceTimer = null;
334
359
  }
360
+ if (transitionEnabled) {
361
+ const currentTransition = container.style.transition || "";
362
+ if (currentTransition.includes(heightTransition)) container.style.transition = currentTransition.replace(heightTransition, "").replace(/\s*,\s*,\s*/g, ", ").replace(/^\s*,\s*|\s*,\s*$/g, "").trim();
363
+ }
335
364
  }
336
365
  function isSuppressed() {
337
366
  return suppressed;
@@ -339,11 +368,16 @@ function createHeightManager(container, computeNext) {
339
368
  function getLastApplied() {
340
369
  return lastApplied;
341
370
  }
371
+ function getTransitionMs() {
372
+ return transitionEnabled ? transitionMs : 0;
373
+ }
342
374
  return {
343
375
  update,
376
+ updateNow,
344
377
  dispose,
345
378
  isSuppressed,
346
- getLastApplied
379
+ getLastApplied,
380
+ getTransitionMs
347
381
  };
348
382
  }
349
383
 
@@ -1434,6 +1468,7 @@ var DiffEditorManager = class DiffEditorManager {
1434
1468
  }
1435
1469
  }
1436
1470
  clearAsyncWork() {
1471
+ this.revealTicketDiff += 1;
1437
1472
  this.cancelRafs();
1438
1473
  this.pendingDiffUpdate = null;
1439
1474
  this.lastKnownModifiedDirty = false;
@@ -3418,6 +3453,7 @@ var DiffEditorManager = class DiffEditorManager {
3418
3453
  refreshDiffPresentation() {
3419
3454
  var _this$diffHideUnchang, _this$diffHeightManag;
3420
3455
  if (!this.diffEditorView) return;
3456
+ this.flushPendingDiffContentSync();
3421
3457
  const hideUnchangedRegions = this.resolveDiffHideUnchangedRegionsOption();
3422
3458
  const shouldRecomputeDiffViewModelForUnchangedRegions = !this.diffHideUnchangedRegionsDeferred && (hideUnchangedRegions === null || hideUnchangedRegions === void 0 ? void 0 : hideUnchangedRegions.enabled) === true && ((_this$diffHideUnchang = this.diffHideUnchangedRegionsResolved) === null || _this$diffHideUnchang === void 0 ? void 0 : _this$diffHideUnchang.enabled) === false && !!this.originalModel && !!this.modifiedModel;
3423
3459
  const presentationOptions = this.resolveDiffPresentationEditorOptions(hideUnchangedRegions);
@@ -4970,7 +5006,6 @@ var DiffEditorManager = class DiffEditorManager {
4970
5006
  this.lastContainer.innerHTML = "";
4971
5007
  this.lastContainer = null;
4972
5008
  }
4973
- this.revealTicketDiff = 0;
4974
5009
  this.lastRevealLineDiff = null;
4975
5010
  this.diffPersistedUnchangedModelState = null;
4976
5011
  this.diffPreviousUnchangedModelState = null;
@@ -4998,7 +5033,6 @@ var DiffEditorManager = class DiffEditorManager {
4998
5033
  this.diffHeightManager.dispose();
4999
5034
  this.diffHeightManager = null;
5000
5035
  }
5001
- this.revealTicketDiff = 0;
5002
5036
  this.lastRevealLineDiff = null;
5003
5037
  this.diffPersistedUnchangedModelState = null;
5004
5038
  this.diffPreviousUnchangedModelState = null;
@@ -5074,6 +5108,12 @@ var DiffEditorManager = class DiffEditorManager {
5074
5108
  }
5075
5109
  }
5076
5110
  }
5111
+ flushPendingDiffContentSync() {
5112
+ this.rafScheduler.cancel("diff");
5113
+ this.flushPendingDiffUpdate();
5114
+ this.flushOriginalAppendBufferSync();
5115
+ this.flushModifiedAppendBufferSync();
5116
+ }
5077
5117
  flushModifiedAppendBufferSync() {
5078
5118
  if (!this.modifiedModel) return;
5079
5119
  if (this.appendBufferModifiedDiff.length === 0) return;
@@ -5271,6 +5311,12 @@ var DiffEditorManager = class DiffEditorManager {
5271
5311
 
5272
5312
  //#endregion
5273
5313
  //#region src/core/EditorManager.ts
5314
+ const defaultHeightTransitionMs = 120;
5315
+ const defaultHeightTransitionEasing = "cubic-bezier(0.4, 0, 0.2, 1)";
5316
+ const smoothHeightTolerancePx = 1;
5317
+ const legacyHeightTolerancePx = 12;
5318
+ const smoothHeightDebounceMs = 16;
5319
+ const legacyHeightDebounceMs = 0;
5274
5320
  var EditorManager = class {
5275
5321
  editorView = null;
5276
5322
  lastContainer = null;
@@ -5317,10 +5363,12 @@ var EditorManager = class {
5317
5363
  appendBufferScheduled = false;
5318
5364
  rafScheduler = createRafScheduler();
5319
5365
  editorHeightManager = null;
5366
+ previousScrollbarGutter = null;
5320
5367
  revealDebounceId = null;
5321
5368
  revealDebounceMs = defaultRevealDebounceMs;
5322
5369
  revealIdleTimerId = null;
5323
5370
  revealTicket = 0;
5371
+ layoutTicket = 0;
5324
5372
  revealStrategyOption;
5325
5373
  revealBatchOnIdleMsOption;
5326
5374
  scrollWatcherSuppressionMs = 500;
@@ -5345,6 +5393,7 @@ var EditorManager = class {
5345
5393
  this.rafScheduler.cancel("maybe-scroll");
5346
5394
  this.rafScheduler.cancel("reveal");
5347
5395
  this.rafScheduler.cancel("immediate-reveal");
5396
+ this.rafScheduler.cancel("layout-after-height");
5348
5397
  this.rafScheduler.cancel("maybe-resume");
5349
5398
  this.rafScheduler.cancel("append");
5350
5399
  }
@@ -5363,6 +5412,8 @@ var EditorManager = class {
5363
5412
  this.appendBuffer.length = 0;
5364
5413
  }
5365
5414
  clearAsyncWork() {
5415
+ this.revealTicket += 1;
5416
+ this.layoutTicket += 1;
5366
5417
  this.cancelRafs();
5367
5418
  this.pendingUpdate = null;
5368
5419
  this.lastKnownCodeDirty = false;
@@ -5407,6 +5458,37 @@ var EditorManager = class {
5407
5458
  if (!m) return false;
5408
5459
  return this._hasScrollBar = m.scrollHeight > m.computedHeight + padding / 2;
5409
5460
  }
5461
+ isSmoothHeightTransitionEnabled() {
5462
+ return this.options.smoothHeightTransition ?? false;
5463
+ }
5464
+ isAutomaticLayoutEnabled() {
5465
+ return this.options.automaticLayout !== false;
5466
+ }
5467
+ getHeightChangeTolerancePx() {
5468
+ return this.options.heightChangeTolerancePx ?? (this.isSmoothHeightTransitionEnabled() ? smoothHeightTolerancePx : legacyHeightTolerancePx);
5469
+ }
5470
+ getHeightManagerOptions() {
5471
+ const smooth = this.isSmoothHeightTransitionEnabled();
5472
+ return {
5473
+ smooth,
5474
+ transitionMs: this.options.heightTransitionMs ?? defaultHeightTransitionMs,
5475
+ transitionEasing: this.options.heightTransitionEasing ?? defaultHeightTransitionEasing,
5476
+ debounceMs: this.options.heightUpdateDebounceMs ?? (smooth ? smoothHeightDebounceMs : legacyHeightDebounceMs),
5477
+ hysteresisPx: this.getHeightChangeTolerancePx()
5478
+ };
5479
+ }
5480
+ setOverflowForHeight(computed$2) {
5481
+ if (!this.lastContainer) return null;
5482
+ const next = computed$2 >= this.maxHeightValue - 1 ? "auto" : "hidden";
5483
+ const prev = this.lastContainer.style.overflow;
5484
+ if (prev !== next) this.lastContainer.style.overflow = next;
5485
+ if (next === "hidden") this._hasScrollBar = false;
5486
+ return {
5487
+ prev,
5488
+ next,
5489
+ changed: prev !== next
5490
+ };
5491
+ }
5410
5492
  userIsNearBottom() {
5411
5493
  if (!this.editorView) return true;
5412
5494
  const m = this.measureViewport();
@@ -5541,46 +5623,89 @@ var EditorManager = class {
5541
5623
  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;
5542
5624
  } catch {}
5543
5625
  }
5544
- isOverflowAuto() {
5545
- try {
5546
- return !!this.lastContainer && this.lastContainer.style.overflow === "auto";
5547
- } catch {
5548
- return false;
5549
- }
5550
- }
5551
- shouldPerformImmediateReveal() {
5552
- return this.autoScrollOnUpdate && this.shouldAutoScroll && this.hasVerticalScrollbar() && this.isOverflowAuto();
5626
+ shouldRevealAfterLayout() {
5627
+ return this.autoScrollOnUpdate && this.shouldAutoScroll;
5628
+ }
5629
+ getRevealSuppressionMs() {
5630
+ var _this$editorHeightMan, _this$editorHeightMan2;
5631
+ const transitionMs = ((_this$editorHeightMan = this.editorHeightManager) === null || _this$editorHeightMan === void 0 || (_this$editorHeightMan2 = _this$editorHeightMan.getTransitionMs) === null || _this$editorHeightMan2 === void 0 ? void 0 : _this$editorHeightMan2.call(_this$editorHeightMan)) ?? 0;
5632
+ return Math.max(this.scrollWatcherSuppressionMs, transitionMs + 100);
5633
+ }
5634
+ syncHeightAndRevealAfterContentChange(targetLine) {
5635
+ const shouldReveal = this.shouldRevealAfterLayout();
5636
+ const willReveal = !!(shouldReveal && this.editorView && this.computedHeight(this.editorView) >= this.maxHeightValue - 1);
5637
+ if (willReveal) this.suppressScrollWatcher(this.getRevealSuppressionMs());
5638
+ const computed$2 = this.syncNonOverflowingLayout();
5639
+ if (computed$2 != null && computed$2 >= this.maxHeightValue - 1 && shouldReveal) {
5640
+ var _this$editorView5;
5641
+ const line = targetLine ?? ((_this$editorView5 = this.editorView) === null || _this$editorView5 === void 0 || (_this$editorView5 = _this$editorView5.getModel()) === null || _this$editorView5 === void 0 ? void 0 : _this$editorView5.getLineCount()) ?? 1;
5642
+ if (this.isSmoothHeightTransitionEnabled()) this.scheduleImmediateRevealAfterLayout(line);
5643
+ else this.forceReveal(line);
5644
+ } else if (!shouldReveal && targetLine != null) this.maybeScrollToBottom(targetLine);
5645
+ return computed$2;
5553
5646
  }
5554
5647
  syncNonOverflowingLayout() {
5555
- var _this$lastContainer$g, _this$lastContainer;
5648
+ var _this$editorHeightMan3, _this$editorHeightMan4;
5556
5649
  if (!this.editorView || !this.lastContainer) return null;
5557
5650
  const computed$2 = this.computedHeight(this.editorView);
5651
+ const needsRevealSync = computed$2 >= this.maxHeightValue - 1 && this.shouldRevealAfterLayout();
5652
+ const useSmoothHeightTransition = this.isSmoothHeightTransitionEnabled();
5653
+ if (needsRevealSync || !useSmoothHeightTransition) (_this$editorHeightMan3 = this.editorHeightManager) === null || _this$editorHeightMan3 === void 0 || _this$editorHeightMan3.updateNow();
5654
+ else (_this$editorHeightMan4 = this.editorHeightManager) === null || _this$editorHeightMan4 === void 0 || _this$editorHeightMan4.update();
5655
+ this.setOverflowForHeight(computed$2);
5558
5656
  if (computed$2 >= this.maxHeightValue - 1) {
5559
- this.lastContainer.style.height = `${this.maxHeightValue}px`;
5657
+ if (useSmoothHeightTransition) this.scheduleLayoutAfterHeightApplied(computed$2);
5560
5658
  return computed$2;
5561
5659
  }
5562
- const currentHeight = Number.parseFloat(this.lastContainer.style.height || "") || ((_this$lastContainer$g = (_this$lastContainer = this.lastContainer).getBoundingClientRect) === null || _this$lastContainer$g === void 0 ? void 0 : _this$lastContainer$g.call(_this$lastContainer).height) || 0;
5563
- if (currentHeight <= 0 || Math.abs(computed$2 - currentHeight) > 12) this.lastContainer.style.height = `${computed$2}px`;
5564
- this.lastContainer.style.overflow = "hidden";
5565
5660
  this._hasScrollBar = false;
5661
+ if (useSmoothHeightTransition) {
5662
+ this.scheduleLayoutAfterHeightApplied(computed$2);
5663
+ try {
5664
+ var _this$editorView$getS3, _this$editorView6, _this$editorView$setS, _this$editorView7;
5665
+ if ((((_this$editorView$getS3 = (_this$editorView6 = this.editorView).getScrollTop) === null || _this$editorView$getS3 === void 0 ? void 0 : _this$editorView$getS3.call(_this$editorView6)) ?? 0) !== 0) (_this$editorView$setS = (_this$editorView7 = this.editorView).setScrollTop) === null || _this$editorView$setS === void 0 || _this$editorView$setS.call(_this$editorView7, 0);
5666
+ this.lastScrollTop = 0;
5667
+ } catch {}
5668
+ return computed$2;
5669
+ }
5566
5670
  try {
5567
- var _this$editorView$layo, _this$editorView5;
5568
- (_this$editorView$layo = (_this$editorView5 = this.editorView).layout) === null || _this$editorView$layo === void 0 || _this$editorView$layo.call(_this$editorView5);
5671
+ var _this$editorView$layo, _this$editorView8;
5672
+ (_this$editorView$layo = (_this$editorView8 = this.editorView).layout) === null || _this$editorView$layo === void 0 || _this$editorView$layo.call(_this$editorView8);
5569
5673
  } catch {}
5570
5674
  try {
5571
- var _this$editorView$getS3, _this$editorView6, _this$editorView$setS, _this$editorView7;
5572
- if ((((_this$editorView$getS3 = (_this$editorView6 = this.editorView).getScrollTop) === null || _this$editorView$getS3 === void 0 ? void 0 : _this$editorView$getS3.call(_this$editorView6)) ?? 0) !== 0) (_this$editorView$setS = (_this$editorView7 = this.editorView).setScrollTop) === null || _this$editorView$setS === void 0 || _this$editorView$setS.call(_this$editorView7, 0);
5675
+ var _this$editorView$getS4, _this$editorView9, _this$editorView$setS2, _this$editorView10;
5676
+ if ((((_this$editorView$getS4 = (_this$editorView9 = this.editorView).getScrollTop) === null || _this$editorView$getS4 === void 0 ? void 0 : _this$editorView$getS4.call(_this$editorView9)) ?? 0) !== 0) (_this$editorView$setS2 = (_this$editorView10 = this.editorView).setScrollTop) === null || _this$editorView$setS2 === void 0 || _this$editorView$setS2.call(_this$editorView10, 0);
5573
5677
  this.lastScrollTop = 0;
5574
5678
  } catch {}
5575
5679
  return computed$2;
5576
5680
  }
5681
+ scheduleLayoutAfterHeightApplied(target) {
5682
+ if (this.isAutomaticLayoutEnabled() || !this.editorView) return;
5683
+ const editor = this.editorView;
5684
+ const ticket = ++this.layoutTicket;
5685
+ this.rafScheduler.schedule("layout-after-height", async () => {
5686
+ try {
5687
+ var _editor$layout;
5688
+ await this.waitForHeightApplied(target, 500);
5689
+ if (ticket !== this.layoutTicket || this.editorView !== editor) return;
5690
+ (_editor$layout = editor.layout) === null || _editor$layout === void 0 || _editor$layout.call(editor);
5691
+ this.measureViewport();
5692
+ } catch (err) {
5693
+ error("EditorManager", "scheduleLayoutAfterHeightApplied error", err);
5694
+ }
5695
+ });
5696
+ }
5577
5697
  async createEditor(container, code, language, currentTheme) {
5578
- var _this$editorView$getS4, _this$editorView8, _this$editorView$getO, _this$editorView9, _this$editorView$getM, _this$editorView$onDi, _this$editorView10;
5698
+ var _this$editorView$getS5, _this$editorView11, _this$editorView$getO, _this$editorView12, _this$editorView$getM, _this$editorView$onDi, _this$editorView13;
5579
5699
  this.cleanup();
5580
5700
  this.lastContainer = container;
5581
5701
  this.initDebugFlag();
5582
5702
  this.dlog("createEditor container, maxHeight", this.maxHeightValue);
5583
5703
  container.style.overflow = "hidden";
5704
+ this.previousScrollbarGutter = null;
5705
+ if (this.isSmoothHeightTransitionEnabled()) {
5706
+ this.previousScrollbarGutter = container.style.scrollbarGutter || "";
5707
+ container.style.scrollbarGutter = "stable";
5708
+ }
5584
5709
  container.style.maxHeight = this.maxHeightCSS;
5585
5710
  this.editorView = monaco_shim_exports.editor.create(container, {
5586
5711
  value: code,
@@ -5614,43 +5739,29 @@ var EditorManager = class {
5614
5739
  this.editorHeightManager = createHeightManager(container, () => {
5615
5740
  const computed$2 = this.computedHeight(this.editorView);
5616
5741
  return Math.min(computed$2, this.maxHeightValue);
5617
- });
5618
- this.editorHeightManager.update();
5619
- const initialComputed = this.computedHeight(this.editorView);
5620
- if (initialComputed >= this.maxHeightValue - 1) {
5621
- container.style.height = `${this.maxHeightValue}px`;
5622
- container.style.overflow = "auto";
5623
- this.dlog("applied immediate maxHeight on createEditor", this.maxHeightValue);
5624
- }
5625
- this.cachedScrollHeight = ((_this$editorView$getS4 = (_this$editorView8 = this.editorView).getScrollHeight) === null || _this$editorView$getS4 === void 0 ? void 0 : _this$editorView$getS4.call(_this$editorView8)) ?? null;
5626
- this.cachedLineHeight = ((_this$editorView$getO = (_this$editorView9 = this.editorView).getOption) === null || _this$editorView$getO === void 0 ? void 0 : _this$editorView$getO.call(_this$editorView9, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? null;
5742
+ }, this.getHeightManagerOptions());
5743
+ const initialComputed = this.editorHeightManager.updateNow();
5744
+ if (initialComputed != null) this.setOverflowForHeight(initialComputed);
5745
+ this.cachedScrollHeight = ((_this$editorView$getS5 = (_this$editorView11 = this.editorView).getScrollHeight) === null || _this$editorView$getS5 === void 0 ? void 0 : _this$editorView$getS5.call(_this$editorView11)) ?? null;
5746
+ this.cachedLineHeight = ((_this$editorView$getO = (_this$editorView12 = this.editorView).getOption) === null || _this$editorView$getO === void 0 ? void 0 : _this$editorView$getO.call(_this$editorView12, monaco_shim_exports.editor.EditorOption.lineHeight)) ?? null;
5627
5747
  this.cachedComputedHeight = this.computedHeight(this.editorView);
5628
5748
  this.cachedLineCount = ((_this$editorView$getM = this.editorView.getModel()) === null || _this$editorView$getM === void 0 ? void 0 : _this$editorView$getM.getLineCount()) ?? null;
5629
- (_this$editorView$onDi = (_this$editorView10 = this.editorView).onDidContentSizeChange) === null || _this$editorView$onDi === void 0 || _this$editorView$onDi.call(_this$editorView10, () => {
5749
+ (_this$editorView$onDi = (_this$editorView13 = this.editorView).onDidContentSizeChange) === null || _this$editorView$onDi === void 0 || _this$editorView$onDi.call(_this$editorView13, () => {
5630
5750
  this._hasScrollBar = false;
5631
5751
  this.rafScheduler.schedule("content-size-change", () => {
5632
5752
  try {
5633
- var _this$editorView11, _this$editorHeightMan, _this$editorHeightMan2;
5753
+ var _this$editorView14, _this$editorHeightMan5;
5634
5754
  this.dlog("content-size-change frame");
5635
- this.cachedLineCount = ((_this$editorView11 = this.editorView) === null || _this$editorView11 === void 0 || (_this$editorView11 = _this$editorView11.getModel()) === null || _this$editorView11 === void 0 ? void 0 : _this$editorView11.getLineCount()) ?? this.cachedLineCount;
5755
+ this.cachedLineCount = ((_this$editorView14 = this.editorView) === null || _this$editorView14 === void 0 || (_this$editorView14 = _this$editorView14.getModel()) === null || _this$editorView14 === void 0 ? void 0 : _this$editorView14.getLineCount()) ?? this.cachedLineCount;
5636
5756
  this.cachedComputedHeight = null;
5637
5757
  const m = this.measureViewport();
5638
5758
  this.dlog("content-size-change measure", m);
5639
- if ((_this$editorHeightMan = this.editorHeightManager) === null || _this$editorHeightMan === void 0 ? void 0 : _this$editorHeightMan.isSuppressed()) {
5759
+ if ((_this$editorHeightMan5 = this.editorHeightManager) === null || _this$editorHeightMan5 === void 0 ? void 0 : _this$editorHeightMan5.isSuppressed()) {
5640
5760
  this.dlog("content-size-change skipped height update (suppressed)");
5641
5761
  return;
5642
5762
  }
5643
- this.dlog("content-size-change calling heightManager.update");
5644
- (_this$editorHeightMan2 = this.editorHeightManager) === null || _this$editorHeightMan2 === void 0 || _this$editorHeightMan2.update();
5645
- const computed$2 = this.computedHeight(this.editorView);
5646
- if (this.lastContainer) {
5647
- const prevOverflow = this.lastContainer.style.overflow;
5648
- const newOverflow = computed$2 >= this.maxHeightValue - 1 ? "auto" : "hidden";
5649
- if (prevOverflow !== newOverflow) {
5650
- this.lastContainer.style.overflow = newOverflow;
5651
- if (newOverflow === "auto" && this.shouldAutoScroll) this.maybeScrollToBottom();
5652
- }
5653
- }
5763
+ this.dlog("content-size-change syncing height/reveal");
5764
+ this.syncHeightAndRevealAfterContentChange();
5654
5765
  } catch (err) {
5655
5766
  error("EditorManager", "content-size-change error", err);
5656
5767
  }
@@ -5718,6 +5829,11 @@ var EditorManager = class {
5718
5829
  if (target !== -1 && this.editorHeightManager) await this.waitForHeightApplied(target, 500);
5719
5830
  else await new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(() => r())));
5720
5831
  this.dlog("running delayed immediate reveal", "ticket=", ticket, "line=", line);
5832
+ if (ticket !== this.revealTicket) {
5833
+ this.dlog("delayed immediate reveal skipped, stale ticket", ticket, "current", this.revealTicket);
5834
+ return;
5835
+ }
5836
+ this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5721
5837
  this.performImmediateReveal(line, ticket);
5722
5838
  } catch (err) {
5723
5839
  error("EditorManager", "scheduleImmediateRevealAfterLayout error", err);
@@ -5726,20 +5842,33 @@ var EditorManager = class {
5726
5842
  }
5727
5843
  waitForHeightApplied(target, timeoutMs = 500) {
5728
5844
  return new Promise((resolve) => {
5845
+ var _this$editorHeightMan6, _this$editorHeightMan7;
5729
5846
  const start = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
5847
+ const tolerance = this.getHeightChangeTolerancePx();
5848
+ const transitionMs = ((_this$editorHeightMan6 = this.editorHeightManager) === null || _this$editorHeightMan6 === void 0 || (_this$editorHeightMan7 = _this$editorHeightMan6.getTransitionMs) === null || _this$editorHeightMan7 === void 0 ? void 0 : _this$editorHeightMan7.call(_this$editorHeightMan6)) ?? 0;
5849
+ let settled = false;
5850
+ const resolveAfterSettle = () => {
5851
+ if (settled) return;
5852
+ settled = true;
5853
+ if (transitionMs > 0) {
5854
+ setTimeout(resolve, transitionMs);
5855
+ return;
5856
+ }
5857
+ requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
5858
+ };
5730
5859
  const check = () => {
5731
5860
  try {
5732
- var _this$editorHeightMan3, _this$editorHeightMan4;
5733
- 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;
5734
- if (last !== -1 && Math.abs(last - target) <= 12) {
5861
+ var _this$editorHeightMan8, _this$editorHeightMan9;
5862
+ const last = ((_this$editorHeightMan8 = this.editorHeightManager) === null || _this$editorHeightMan8 === void 0 || (_this$editorHeightMan9 = _this$editorHeightMan8.getLastApplied) === null || _this$editorHeightMan9 === void 0 ? void 0 : _this$editorHeightMan9.call(_this$editorHeightMan8)) ?? -1;
5863
+ if (last !== -1 && Math.abs(last - target) <= tolerance) {
5735
5864
  this.dlog("waitForHeightApplied satisfied", last, "target=", target);
5736
- resolve();
5865
+ resolveAfterSettle();
5737
5866
  return;
5738
5867
  }
5739
5868
  const now = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
5740
5869
  if (now - start > timeoutMs) {
5741
5870
  log("EditorManager", "waitForHeightApplied timeout", last, "target=", target);
5742
- resolve();
5871
+ resolveAfterSettle();
5743
5872
  return;
5744
5873
  }
5745
5874
  } catch {}
@@ -5791,12 +5920,7 @@ var EditorManager = class {
5791
5920
  const newLineCount$1 = model.getLineCount();
5792
5921
  this.cachedLineCount = newLineCount$1;
5793
5922
  this.cachedComputedHeight = null;
5794
- if (newLineCount$1 !== prevLineCount$1) {
5795
- const shouldImmediate = this.shouldPerformImmediateReveal();
5796
- if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5797
- const computed$2 = this.syncNonOverflowingLayout();
5798
- if (computed$2 != null && computed$2 >= this.maxHeightValue - 1) this.forceReveal(newLineCount$1);
5799
- }
5923
+ if (newLineCount$1 !== prevLineCount$1) this.syncHeightAndRevealAfterContentChange(newLineCount$1);
5800
5924
  return;
5801
5925
  }
5802
5926
  let prevCode;
@@ -5826,13 +5950,7 @@ var EditorManager = class {
5826
5950
  const newLineCount = model.getLineCount();
5827
5951
  this.cachedLineCount = newLineCount;
5828
5952
  this.cachedComputedHeight = null;
5829
- if (newLineCount !== prevLineCount) {
5830
- const shouldImmediate = this.shouldPerformImmediateReveal();
5831
- if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5832
- this.syncNonOverflowingLayout();
5833
- if (shouldImmediate) this.scheduleImmediateRevealAfterLayout(newLineCount);
5834
- else this.maybeScrollToBottom(newLineCount);
5835
- }
5953
+ if (newLineCount !== prevLineCount) this.syncHeightAndRevealAfterContentChange(newLineCount);
5836
5954
  }
5837
5955
  appendCode(appendText, codeLanguage) {
5838
5956
  if (!this.editorView) return;
@@ -5864,10 +5982,7 @@ var EditorManager = class {
5864
5982
  this.lastKnownCode = next;
5865
5983
  const newLineCount = model.getLineCount();
5866
5984
  this.cachedLineCount = newLineCount;
5867
- if (newLineCount !== prevLineCount) {
5868
- this.syncNonOverflowingLayout();
5869
- this.maybeScrollToBottom(newLineCount);
5870
- }
5985
+ if (newLineCount !== prevLineCount) this.syncHeightAndRevealAfterContentChange(newLineCount);
5871
5986
  return;
5872
5987
  }
5873
5988
  const res = computeMinimalEdit(prev, next);
@@ -5920,13 +6035,7 @@ var EditorManager = class {
5920
6035
  if (lastLine !== newLineCount) {
5921
6036
  this.cachedLineCount = newLineCount;
5922
6037
  this.cachedComputedHeight = null;
5923
- const shouldImmediate = this.shouldPerformImmediateReveal();
5924
- if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5925
- this.syncNonOverflowingLayout();
5926
- if (shouldImmediate) try {
5927
- this.forceReveal(newLineCount);
5928
- } catch {}
5929
- else this.maybeScrollToBottom(newLineCount);
6038
+ this.syncHeightAndRevealAfterContentChange(newLineCount);
5930
6039
  }
5931
6040
  }
5932
6041
  setLanguage(language, languages$1) {
@@ -5941,8 +6050,8 @@ var EditorManager = class {
5941
6050
  return this.editorView;
5942
6051
  }
5943
6052
  getCode() {
5944
- var _this$editorView12;
5945
- return ((_this$editorView12 = this.editorView) === null || _this$editorView12 === void 0 || (_this$editorView12 = _this$editorView12.getModel()) === null || _this$editorView12 === void 0 ? void 0 : _this$editorView12.getValue()) ?? null;
6053
+ var _this$editorView15;
6054
+ return ((_this$editorView15 = this.editorView) === null || _this$editorView15 === void 0 || (_this$editorView15 = _this$editorView15.getModel()) === null || _this$editorView15 === void 0 ? void 0 : _this$editorView15.getValue()) ?? null;
5946
6055
  }
5947
6056
  setUpdateThrottleMs(ms) {
5948
6057
  this.updateThrottleMs = ms;
@@ -5963,6 +6072,8 @@ var EditorManager = class {
5963
6072
  }
5964
6073
  this.lastKnownCode = null;
5965
6074
  if (this.lastContainer) {
6075
+ if (this.previousScrollbarGutter != null) this.lastContainer.style.scrollbarGutter = this.previousScrollbarGutter;
6076
+ this.previousScrollbarGutter = null;
5966
6077
  this.lastContainer.style.minHeight = "";
5967
6078
  this.lastContainer.innerHTML = "";
5968
6079
  this.lastContainer = null;
@@ -5987,6 +6098,8 @@ var EditorManager = class {
5987
6098
  this._hasScrollBar = false;
5988
6099
  this.shouldAutoScroll = !!this.autoScrollInitial;
5989
6100
  this.lastScrollTop = 0;
6101
+ if (this.lastContainer && this.previousScrollbarGutter != null) this.lastContainer.style.scrollbarGutter = this.previousScrollbarGutter;
6102
+ this.previousScrollbarGutter = null;
5990
6103
  if (this.editorHeightManager) {
5991
6104
  this.editorHeightManager.dispose();
5992
6105
  this.editorHeightManager = null;
@@ -6293,7 +6406,7 @@ let globalAppliedThemeName = null;
6293
6406
  * @param {MonacoLanguage[]} [monacoOptions.languages] - 支持的编程语言数组
6294
6407
  * @param {string} [monacoOptions.theme] - 初始主题名称
6295
6408
  * @param {boolean} [monacoOptions.isCleanOnBeforeCreate] - 是否在创建前清理之前注册的资源, 默认为 true
6296
- * @param {(monaco: typeof import('monaco-editor')) => monaco.IDisposable[]} [monacoOptions.onBeforeCreate] - 编辑器创建前的钩子函数
6409
+ * @param {(monaco: typeof import('monaco-editor/esm/vs/editor/editor.api')) => monaco.IDisposable[]} [monacoOptions.onBeforeCreate] - 编辑器创建前的钩子函数
6297
6410
  *
6298
6411
  * @returns {{
6299
6412
  * createEditor: (container: HTMLElement, code: string, language: string) => Promise<monaco.editor.IStandaloneCodeEditor>,
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "stream-monaco",
3
3
  "type": "module",
4
- "version": "0.0.39",
5
- "packageManager": "pnpm@10.33.2",
4
+ "version": "0.0.41",
6
5
  "description": "A framework-agnostic Monaco Editor integration with Shiki syntax highlighting, built for real-time streaming updates and efficient diff editing.",
7
6
  "author": "Simon He",
8
7
  "license": "MIT",
@@ -74,33 +73,6 @@
74
73
  "legacy.d.ts",
75
74
  "legacy.js"
76
75
  ],
77
- "scripts": {
78
- "build": "tsdown",
79
- "dev": "npm run build -- --watch src",
80
- "format": "prettier --write --cache .",
81
- "lint": "eslint . --cache",
82
- "lint:fix": "pnpm run lint --fix",
83
- "prepublishOnly": "pnpm build",
84
- "release": "bumpp --tag \"v%s\"",
85
- "publish:package": "pnpm build && npm publish",
86
- "start": "esno src/index.ts",
87
- "bench": "node scripts/stream-benchmark.mjs",
88
- "bench:playwright": "node scripts/playwright-bench.mjs",
89
- "smoke:diff": "node scripts/playwright-diff-smoke.mjs",
90
- "shot:diff-ux": "node scripts/playwright-diff-ux-shot.mjs",
91
- "validate:diff-gutter": "node scripts/playwright-diff-gutter-validate.mjs",
92
- "validate:diff-hunk-actions": "node scripts/playwright-diff-hunk-actions-validate.mjs",
93
- "validate:diff-hunk-custom-flow": "node scripts/playwright-diff-hunk-custom-flow-validate.mjs",
94
- "validate:diff-hunk-update-diff-flow": "node scripts/playwright-diff-hunk-update-diff-flow-validate.mjs",
95
- "validate:diff-inline": "node scripts/playwright-diff-inline-validate.mjs",
96
- "validate:diff-transition": "node scripts/playwright-diff-transition-validate.mjs",
97
- "validate:diff-unchanged-expand": "node scripts/playwright-diff-unchanged-expand-validate.mjs",
98
- "validate:diff-unchanged-reveal": "node scripts/playwright-diff-unchanged-reveal-validate.mjs",
99
- "validate:markstream-diff-theme": "node scripts/playwright-markstream-diff-theme-validate.mjs",
100
- "compare:diff-ux": "node scripts/playwright-diff-ux-compare.mjs",
101
- "test": "vitest",
102
- "typecheck": "tsc --noEmit"
103
- },
104
76
  "peerDependencies": {
105
77
  "monaco-editor": ">=0.52.2 <0.56.0"
106
78
  },
@@ -129,5 +101,32 @@
129
101
  "prettier --write --cache --ignore-unknown"
130
102
  ],
131
103
  "*.{vue,js,ts,jsx,tsx,md,json}": "eslint --fix"
104
+ },
105
+ "scripts": {
106
+ "build": "tsdown",
107
+ "dev": "npm run build -- --watch src",
108
+ "format": "prettier --write --cache .",
109
+ "lint": "eslint . --cache",
110
+ "lint:fix": "pnpm run lint --fix",
111
+ "release": "bumpp --tag \"v%s\"",
112
+ "publish:package": "pnpm build && npm publish",
113
+ "start": "esno src/index.ts",
114
+ "bench": "node scripts/stream-benchmark.mjs",
115
+ "bench:playwright": "node scripts/playwright-bench.mjs",
116
+ "smoke:diff": "node scripts/playwright-diff-smoke.mjs",
117
+ "smoke:height-stability": "node scripts/playwright-height-stability-smoke.mjs",
118
+ "shot:diff-ux": "node scripts/playwright-diff-ux-shot.mjs",
119
+ "validate:diff-gutter": "node scripts/playwright-diff-gutter-validate.mjs",
120
+ "validate:diff-hunk-actions": "node scripts/playwright-diff-hunk-actions-validate.mjs",
121
+ "validate:diff-hunk-custom-flow": "node scripts/playwright-diff-hunk-custom-flow-validate.mjs",
122
+ "validate:diff-hunk-update-diff-flow": "node scripts/playwright-diff-hunk-update-diff-flow-validate.mjs",
123
+ "validate:diff-inline": "node scripts/playwright-diff-inline-validate.mjs",
124
+ "validate:diff-transition": "node scripts/playwright-diff-transition-validate.mjs",
125
+ "validate:diff-unchanged-expand": "node scripts/playwright-diff-unchanged-expand-validate.mjs",
126
+ "validate:diff-unchanged-reveal": "node scripts/playwright-diff-unchanged-reveal-validate.mjs",
127
+ "validate:markstream-diff-theme": "node scripts/playwright-markstream-diff-theme-validate.mjs",
128
+ "compare:diff-ux": "node scripts/playwright-diff-ux-compare.mjs",
129
+ "test": "vitest",
130
+ "typecheck": "tsc --noEmit"
132
131
  }
133
- }
132
+ }