stream-monaco 0.0.40 → 0.0.42

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.
@@ -269,32 +269,45 @@ function error(tag, ...args) {
269
269
 
270
270
  //#endregion
271
271
  //#region src/utils/height.ts
272
- function createHeightManager(container, computeNext) {
272
+ const DEFAULT_TRANSITION_MS = 120;
273
+ const DEFAULT_TRANSITION_EASING = "cubic-bezier(0.4, 0, 0.2, 1)";
274
+ const DEFAULT_HYSTERESIS_PX = 12;
275
+ const DEFAULT_DEBOUNCE_MS = 0;
276
+ function prefersReducedMotion() {
277
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
278
+ }
279
+ function createHeightManager(container, computeNext, options = {}) {
280
+ const transitionMs = Math.max(0, options.transitionMs ?? DEFAULT_TRANSITION_MS);
281
+ const transitionEasing = options.transitionEasing ?? DEFAULT_TRANSITION_EASING;
282
+ const hysteresisPx = Math.max(0, options.hysteresisPx ?? DEFAULT_HYSTERESIS_PX);
283
+ const debounceMs = Math.max(0, options.debounceMs ?? DEFAULT_DEBOUNCE_MS);
284
+ const transitionEnabled = options.smooth === true && transitionMs > 0 && !prefersReducedMotion();
285
+ const previousTransition = container.style.transition || "";
286
+ const heightTransition = `height ${transitionMs}ms ${transitionEasing}`;
287
+ if (transitionEnabled) container.style.transition = previousTransition ? `${previousTransition}, ${heightTransition}` : heightTransition;
273
288
  let raf = null;
274
289
  let debounceTimer = null;
275
290
  let lastApplied = -1;
276
291
  let suppressed = false;
277
- const HYSTERESIS_PX = 12;
278
- const DEBOUNCE_MS = 0;
279
292
  function apply() {
280
293
  var _container$getBoundin;
281
294
  const next = computeNext();
282
- if (next == null) return;
295
+ if (next == null) return null;
283
296
  log("heightManager", "computeNext ->", {
284
297
  next,
285
298
  lastApplied
286
299
  });
287
300
  if (!Number.isFinite(next) || next <= 0) {
288
301
  log("heightManager", "invalid next height, ignoring", next);
289
- return;
302
+ return null;
290
303
  }
291
304
  const currentHeight = Number.parseFloat(container.style.height || "") || ((_container$getBoundin = container.getBoundingClientRect) === null || _container$getBoundin === void 0 ? void 0 : _container$getBoundin.call(container).height) || 0;
292
- if (currentHeight > 0 && Math.abs(next - currentHeight) <= HYSTERESIS_PX) {
305
+ if (currentHeight > 0 && Math.abs(next - currentHeight) <= hysteresisPx) {
293
306
  lastApplied = next;
294
- return;
307
+ return next;
295
308
  }
296
- if (lastApplied !== -1 && Math.abs(next - lastApplied) <= HYSTERESIS_PX) return;
297
- if (next === lastApplied) return;
309
+ if (lastApplied !== -1 && Math.abs(next - lastApplied) <= hysteresisPx) return next;
310
+ if (next === lastApplied) return next;
298
311
  suppressed = true;
299
312
  container.style.height = `${next}px`;
300
313
  lastApplied = next;
@@ -302,13 +315,14 @@ function createHeightManager(container, computeNext) {
302
315
  queueMicrotask(() => {
303
316
  suppressed = false;
304
317
  });
318
+ return next;
305
319
  }
306
320
  function scheduleApply() {
307
321
  if (debounceTimer != null) {
308
322
  clearTimeout(debounceTimer);
309
323
  debounceTimer = null;
310
324
  }
311
- if (DEBOUNCE_MS === 0) {
325
+ if (debounceMs === 0) {
312
326
  if (raf != null) return;
313
327
  raf = requestAnimationFrame(() => {
314
328
  raf = null;
@@ -323,11 +337,22 @@ function createHeightManager(container, computeNext) {
323
337
  raf = null;
324
338
  apply();
325
339
  });
326
- }, DEBOUNCE_MS);
340
+ }, debounceMs);
327
341
  }
328
342
  function update() {
329
343
  scheduleApply();
330
344
  }
345
+ function updateNow() {
346
+ if (raf != null) {
347
+ cancelAnimationFrame(raf);
348
+ raf = null;
349
+ }
350
+ if (debounceTimer != null) {
351
+ clearTimeout(debounceTimer);
352
+ debounceTimer = null;
353
+ }
354
+ return apply();
355
+ }
331
356
  function dispose() {
332
357
  if (raf != null) {
333
358
  cancelAnimationFrame(raf);
@@ -337,6 +362,10 @@ function createHeightManager(container, computeNext) {
337
362
  clearTimeout(debounceTimer);
338
363
  debounceTimer = null;
339
364
  }
365
+ if (transitionEnabled) {
366
+ const currentTransition = container.style.transition || "";
367
+ if (currentTransition.includes(heightTransition)) container.style.transition = currentTransition.replace(heightTransition, "").replace(/\s*,\s*,\s*/g, ", ").replace(/^\s*,\s*|\s*,\s*$/g, "").trim();
368
+ }
340
369
  }
341
370
  function isSuppressed() {
342
371
  return suppressed;
@@ -344,11 +373,16 @@ function createHeightManager(container, computeNext) {
344
373
  function getLastApplied() {
345
374
  return lastApplied;
346
375
  }
376
+ function getTransitionMs() {
377
+ return transitionEnabled ? transitionMs : 0;
378
+ }
347
379
  return {
348
380
  update,
381
+ updateNow,
349
382
  dispose,
350
383
  isSuppressed,
351
- getLastApplied
384
+ getLastApplied,
385
+ getTransitionMs
352
386
  };
353
387
  }
354
388
 
@@ -1439,6 +1473,7 @@ var DiffEditorManager = class DiffEditorManager {
1439
1473
  }
1440
1474
  }
1441
1475
  clearAsyncWork() {
1476
+ this.revealTicketDiff += 1;
1442
1477
  this.cancelRafs();
1443
1478
  this.pendingDiffUpdate = null;
1444
1479
  this.lastKnownModifiedDirty = false;
@@ -4081,6 +4116,8 @@ var DiffEditorManager = class DiffEditorManager {
4081
4116
  this.createDomDisposable(this.diffHunkDisposables, this.diffHunkUpperNode, "mouseleave", () => this.scheduleHideDiffHunkActions());
4082
4117
  this.createDomDisposable(this.diffHunkDisposables, this.diffHunkLowerNode, "mouseenter", () => this.cancelScheduledHideDiffHunkActions());
4083
4118
  this.createDomDisposable(this.diffHunkDisposables, this.diffHunkLowerNode, "mouseleave", () => this.scheduleHideDiffHunkActions());
4119
+ this.createDomDisposable(this.diffHunkDisposables, this.diffHunkUpperNode, "wheel", (event) => this.handleDiffHunkWheel(event, "upper"));
4120
+ this.createDomDisposable(this.diffHunkDisposables, this.diffHunkLowerNode, "wheel", (event) => this.handleDiffHunkWheel(event, "lower"));
4084
4121
  overlay.append(this.diffHunkUpperNode, this.diffHunkLowerNode);
4085
4122
  const originalEditor = this.diffEditorView.getOriginalEditor();
4086
4123
  const modifiedEditor = this.diffEditorView.getModifiedEditor();
@@ -4104,6 +4141,17 @@ var DiffEditorManager = class DiffEditorManager {
4104
4141
  }));
4105
4142
  this.diffHunkLineChanges = this.getEffectiveLineChanges();
4106
4143
  }
4144
+ handleDiffHunkWheel(event, side) {
4145
+ var _editor$setScrollLeft, _editor$getScrollLeft, _editor$setScrollTop, _editor$getScrollTop2;
4146
+ if (Math.abs(event.deltaX) < .5 && Math.abs(event.deltaY) < .5) return;
4147
+ if (!this.diffEditorView) return;
4148
+ const editor = this.isDiffInlineMode() || side === "lower" ? this.diffEditorView.getModifiedEditor() : this.diffEditorView.getOriginalEditor();
4149
+ event.preventDefault();
4150
+ event.stopPropagation();
4151
+ (_editor$setScrollLeft = editor.setScrollLeft) === null || _editor$setScrollLeft === void 0 || _editor$setScrollLeft.call(editor, (((_editor$getScrollLeft = editor.getScrollLeft) === null || _editor$getScrollLeft === void 0 ? void 0 : _editor$getScrollLeft.call(editor)) ?? 0) + event.deltaX);
4152
+ (_editor$setScrollTop = editor.setScrollTop) === null || _editor$setScrollTop === void 0 || _editor$setScrollTop.call(editor, (((_editor$getScrollTop2 = editor.getScrollTop) === null || _editor$getScrollTop2 === void 0 ? void 0 : _editor$getScrollTop2.call(editor)) ?? 0) + event.deltaY);
4153
+ this.hideDiffHunkActions();
4154
+ }
4107
4155
  cancelScheduledHideDiffHunkActions() {
4108
4156
  if (this.diffHunkHideTimer != null) {
4109
4157
  clearTimeout(this.diffHunkHideTimer);
@@ -4976,7 +5024,6 @@ var DiffEditorManager = class DiffEditorManager {
4976
5024
  this.lastContainer.innerHTML = "";
4977
5025
  this.lastContainer = null;
4978
5026
  }
4979
- this.revealTicketDiff = 0;
4980
5027
  this.lastRevealLineDiff = null;
4981
5028
  this.diffPersistedUnchangedModelState = null;
4982
5029
  this.diffPreviousUnchangedModelState = null;
@@ -5004,7 +5051,6 @@ var DiffEditorManager = class DiffEditorManager {
5004
5051
  this.diffHeightManager.dispose();
5005
5052
  this.diffHeightManager = null;
5006
5053
  }
5007
- this.revealTicketDiff = 0;
5008
5054
  this.lastRevealLineDiff = null;
5009
5055
  this.diffPersistedUnchangedModelState = null;
5010
5056
  this.diffPreviousUnchangedModelState = null;
@@ -5283,6 +5329,12 @@ var DiffEditorManager = class DiffEditorManager {
5283
5329
 
5284
5330
  //#endregion
5285
5331
  //#region src/core/EditorManager.ts
5332
+ const defaultHeightTransitionMs = 120;
5333
+ const defaultHeightTransitionEasing = "cubic-bezier(0.4, 0, 0.2, 1)";
5334
+ const smoothHeightTolerancePx = 1;
5335
+ const legacyHeightTolerancePx = 12;
5336
+ const smoothHeightDebounceMs = 16;
5337
+ const legacyHeightDebounceMs = 0;
5286
5338
  var EditorManager = class {
5287
5339
  editorView = null;
5288
5340
  lastContainer = null;
@@ -5329,10 +5381,12 @@ var EditorManager = class {
5329
5381
  appendBufferScheduled = false;
5330
5382
  rafScheduler = createRafScheduler();
5331
5383
  editorHeightManager = null;
5384
+ previousScrollbarGutter = null;
5332
5385
  revealDebounceId = null;
5333
5386
  revealDebounceMs = defaultRevealDebounceMs;
5334
5387
  revealIdleTimerId = null;
5335
5388
  revealTicket = 0;
5389
+ layoutTicket = 0;
5336
5390
  revealStrategyOption;
5337
5391
  revealBatchOnIdleMsOption;
5338
5392
  scrollWatcherSuppressionMs = 500;
@@ -5357,6 +5411,7 @@ var EditorManager = class {
5357
5411
  this.rafScheduler.cancel("maybe-scroll");
5358
5412
  this.rafScheduler.cancel("reveal");
5359
5413
  this.rafScheduler.cancel("immediate-reveal");
5414
+ this.rafScheduler.cancel("layout-after-height");
5360
5415
  this.rafScheduler.cancel("maybe-resume");
5361
5416
  this.rafScheduler.cancel("append");
5362
5417
  }
@@ -5375,6 +5430,8 @@ var EditorManager = class {
5375
5430
  this.appendBuffer.length = 0;
5376
5431
  }
5377
5432
  clearAsyncWork() {
5433
+ this.revealTicket += 1;
5434
+ this.layoutTicket += 1;
5378
5435
  this.cancelRafs();
5379
5436
  this.pendingUpdate = null;
5380
5437
  this.lastKnownCodeDirty = false;
@@ -5419,6 +5476,37 @@ var EditorManager = class {
5419
5476
  if (!m) return false;
5420
5477
  return this._hasScrollBar = m.scrollHeight > m.computedHeight + padding / 2;
5421
5478
  }
5479
+ isSmoothHeightTransitionEnabled() {
5480
+ return this.options.smoothHeightTransition ?? false;
5481
+ }
5482
+ isAutomaticLayoutEnabled() {
5483
+ return this.options.automaticLayout !== false;
5484
+ }
5485
+ getHeightChangeTolerancePx() {
5486
+ return this.options.heightChangeTolerancePx ?? (this.isSmoothHeightTransitionEnabled() ? smoothHeightTolerancePx : legacyHeightTolerancePx);
5487
+ }
5488
+ getHeightManagerOptions() {
5489
+ const smooth = this.isSmoothHeightTransitionEnabled();
5490
+ return {
5491
+ smooth,
5492
+ transitionMs: this.options.heightTransitionMs ?? defaultHeightTransitionMs,
5493
+ transitionEasing: this.options.heightTransitionEasing ?? defaultHeightTransitionEasing,
5494
+ debounceMs: this.options.heightUpdateDebounceMs ?? (smooth ? smoothHeightDebounceMs : legacyHeightDebounceMs),
5495
+ hysteresisPx: this.getHeightChangeTolerancePx()
5496
+ };
5497
+ }
5498
+ setOverflowForHeight(computed$1) {
5499
+ if (!this.lastContainer) return null;
5500
+ const next = computed$1 >= this.maxHeightValue - 1 ? "auto" : "hidden";
5501
+ const prev = this.lastContainer.style.overflow;
5502
+ if (prev !== next) this.lastContainer.style.overflow = next;
5503
+ if (next === "hidden") this._hasScrollBar = false;
5504
+ return {
5505
+ prev,
5506
+ next,
5507
+ changed: prev !== next
5508
+ };
5509
+ }
5422
5510
  userIsNearBottom() {
5423
5511
  if (!this.editorView) return true;
5424
5512
  const m = this.measureViewport();
@@ -5553,46 +5641,89 @@ var EditorManager = class {
5553
5641
  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;
5554
5642
  } catch {}
5555
5643
  }
5556
- isOverflowAuto() {
5557
- try {
5558
- return !!this.lastContainer && this.lastContainer.style.overflow === "auto";
5559
- } catch {
5560
- return false;
5561
- }
5562
- }
5563
- shouldPerformImmediateReveal() {
5564
- return this.autoScrollOnUpdate && this.shouldAutoScroll && this.hasVerticalScrollbar() && this.isOverflowAuto();
5644
+ shouldRevealAfterLayout() {
5645
+ return this.autoScrollOnUpdate && this.shouldAutoScroll;
5646
+ }
5647
+ getRevealSuppressionMs() {
5648
+ var _this$editorHeightMan, _this$editorHeightMan2;
5649
+ 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;
5650
+ return Math.max(this.scrollWatcherSuppressionMs, transitionMs + 100);
5651
+ }
5652
+ syncHeightAndRevealAfterContentChange(targetLine) {
5653
+ const shouldReveal = this.shouldRevealAfterLayout();
5654
+ const willReveal = !!(shouldReveal && this.editorView && this.computedHeight(this.editorView) >= this.maxHeightValue - 1);
5655
+ if (willReveal) this.suppressScrollWatcher(this.getRevealSuppressionMs());
5656
+ const computed$1 = this.syncNonOverflowingLayout();
5657
+ if (computed$1 != null && computed$1 >= this.maxHeightValue - 1 && shouldReveal) {
5658
+ var _this$editorView5;
5659
+ 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;
5660
+ if (this.isSmoothHeightTransitionEnabled()) this.scheduleImmediateRevealAfterLayout(line);
5661
+ else this.forceReveal(line);
5662
+ } else if (!shouldReveal && targetLine != null) this.maybeScrollToBottom(targetLine);
5663
+ return computed$1;
5565
5664
  }
5566
5665
  syncNonOverflowingLayout() {
5567
- var _this$lastContainer$g, _this$lastContainer;
5666
+ var _this$editorHeightMan3, _this$editorHeightMan4;
5568
5667
  if (!this.editorView || !this.lastContainer) return null;
5569
5668
  const computed$1 = this.computedHeight(this.editorView);
5669
+ const needsRevealSync = computed$1 >= this.maxHeightValue - 1 && this.shouldRevealAfterLayout();
5670
+ const useSmoothHeightTransition = this.isSmoothHeightTransitionEnabled();
5671
+ if (needsRevealSync || !useSmoothHeightTransition) (_this$editorHeightMan3 = this.editorHeightManager) === null || _this$editorHeightMan3 === void 0 || _this$editorHeightMan3.updateNow();
5672
+ else (_this$editorHeightMan4 = this.editorHeightManager) === null || _this$editorHeightMan4 === void 0 || _this$editorHeightMan4.update();
5673
+ this.setOverflowForHeight(computed$1);
5570
5674
  if (computed$1 >= this.maxHeightValue - 1) {
5571
- this.lastContainer.style.height = `${this.maxHeightValue}px`;
5675
+ if (useSmoothHeightTransition) this.scheduleLayoutAfterHeightApplied(computed$1);
5572
5676
  return computed$1;
5573
5677
  }
5574
- 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;
5575
- if (currentHeight <= 0 || Math.abs(computed$1 - currentHeight) > 12) this.lastContainer.style.height = `${computed$1}px`;
5576
- this.lastContainer.style.overflow = "hidden";
5577
5678
  this._hasScrollBar = false;
5679
+ if (useSmoothHeightTransition) {
5680
+ this.scheduleLayoutAfterHeightApplied(computed$1);
5681
+ try {
5682
+ var _this$editorView$getS3, _this$editorView6, _this$editorView$setS, _this$editorView7;
5683
+ 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);
5684
+ this.lastScrollTop = 0;
5685
+ } catch {}
5686
+ return computed$1;
5687
+ }
5578
5688
  try {
5579
- var _this$editorView$layo, _this$editorView5;
5580
- (_this$editorView$layo = (_this$editorView5 = this.editorView).layout) === null || _this$editorView$layo === void 0 || _this$editorView$layo.call(_this$editorView5);
5689
+ var _this$editorView$layo, _this$editorView8;
5690
+ (_this$editorView$layo = (_this$editorView8 = this.editorView).layout) === null || _this$editorView$layo === void 0 || _this$editorView$layo.call(_this$editorView8);
5581
5691
  } catch {}
5582
5692
  try {
5583
- var _this$editorView$getS3, _this$editorView6, _this$editorView$setS, _this$editorView7;
5584
- 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);
5693
+ var _this$editorView$getS4, _this$editorView9, _this$editorView$setS2, _this$editorView10;
5694
+ 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);
5585
5695
  this.lastScrollTop = 0;
5586
5696
  } catch {}
5587
5697
  return computed$1;
5588
5698
  }
5699
+ scheduleLayoutAfterHeightApplied(target) {
5700
+ if (this.isAutomaticLayoutEnabled() || !this.editorView) return;
5701
+ const editor = this.editorView;
5702
+ const ticket = ++this.layoutTicket;
5703
+ this.rafScheduler.schedule("layout-after-height", async () => {
5704
+ try {
5705
+ var _editor$layout;
5706
+ await this.waitForHeightApplied(target, 500);
5707
+ if (ticket !== this.layoutTicket || this.editorView !== editor) return;
5708
+ (_editor$layout = editor.layout) === null || _editor$layout === void 0 || _editor$layout.call(editor);
5709
+ this.measureViewport();
5710
+ } catch (err) {
5711
+ error("EditorManager", "scheduleLayoutAfterHeightApplied error", err);
5712
+ }
5713
+ });
5714
+ }
5589
5715
  async createEditor(container, code, language, currentTheme) {
5590
- var _this$editorView$getS4, _this$editorView8, _this$editorView$getO, _this$editorView9, _this$editorView$getM, _this$editorView$onDi, _this$editorView10;
5716
+ var _this$editorView$getS5, _this$editorView11, _this$editorView$getO, _this$editorView12, _this$editorView$getM, _this$editorView$onDi, _this$editorView13;
5591
5717
  this.cleanup();
5592
5718
  this.lastContainer = container;
5593
5719
  this.initDebugFlag();
5594
5720
  this.dlog("createEditor container, maxHeight", this.maxHeightValue);
5595
5721
  container.style.overflow = "hidden";
5722
+ this.previousScrollbarGutter = null;
5723
+ if (this.isSmoothHeightTransitionEnabled()) {
5724
+ this.previousScrollbarGutter = container.style.scrollbarGutter || "";
5725
+ container.style.scrollbarGutter = "stable";
5726
+ }
5596
5727
  container.style.maxHeight = this.maxHeightCSS;
5597
5728
  this.editorView = monaco_shim_exports.editor.create(container, {
5598
5729
  value: code,
@@ -5626,43 +5757,29 @@ var EditorManager = class {
5626
5757
  this.editorHeightManager = createHeightManager(container, () => {
5627
5758
  const computed$1 = this.computedHeight(this.editorView);
5628
5759
  return Math.min(computed$1, this.maxHeightValue);
5629
- });
5630
- this.editorHeightManager.update();
5631
- const initialComputed = this.computedHeight(this.editorView);
5632
- if (initialComputed >= this.maxHeightValue - 1) {
5633
- container.style.height = `${this.maxHeightValue}px`;
5634
- container.style.overflow = "auto";
5635
- this.dlog("applied immediate maxHeight on createEditor", this.maxHeightValue);
5636
- }
5637
- 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;
5638
- 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;
5760
+ }, this.getHeightManagerOptions());
5761
+ const initialComputed = this.editorHeightManager.updateNow();
5762
+ if (initialComputed != null) this.setOverflowForHeight(initialComputed);
5763
+ 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;
5764
+ 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;
5639
5765
  this.cachedComputedHeight = this.computedHeight(this.editorView);
5640
5766
  this.cachedLineCount = ((_this$editorView$getM = this.editorView.getModel()) === null || _this$editorView$getM === void 0 ? void 0 : _this$editorView$getM.getLineCount()) ?? null;
5641
- (_this$editorView$onDi = (_this$editorView10 = this.editorView).onDidContentSizeChange) === null || _this$editorView$onDi === void 0 || _this$editorView$onDi.call(_this$editorView10, () => {
5767
+ (_this$editorView$onDi = (_this$editorView13 = this.editorView).onDidContentSizeChange) === null || _this$editorView$onDi === void 0 || _this$editorView$onDi.call(_this$editorView13, () => {
5642
5768
  this._hasScrollBar = false;
5643
5769
  this.rafScheduler.schedule("content-size-change", () => {
5644
5770
  try {
5645
- var _this$editorView11, _this$editorHeightMan, _this$editorHeightMan2;
5771
+ var _this$editorView14, _this$editorHeightMan5;
5646
5772
  this.dlog("content-size-change frame");
5647
- 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;
5773
+ 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;
5648
5774
  this.cachedComputedHeight = null;
5649
5775
  const m = this.measureViewport();
5650
5776
  this.dlog("content-size-change measure", m);
5651
- if ((_this$editorHeightMan = this.editorHeightManager) === null || _this$editorHeightMan === void 0 ? void 0 : _this$editorHeightMan.isSuppressed()) {
5777
+ if ((_this$editorHeightMan5 = this.editorHeightManager) === null || _this$editorHeightMan5 === void 0 ? void 0 : _this$editorHeightMan5.isSuppressed()) {
5652
5778
  this.dlog("content-size-change skipped height update (suppressed)");
5653
5779
  return;
5654
5780
  }
5655
- this.dlog("content-size-change calling heightManager.update");
5656
- (_this$editorHeightMan2 = this.editorHeightManager) === null || _this$editorHeightMan2 === void 0 || _this$editorHeightMan2.update();
5657
- const computed$1 = this.computedHeight(this.editorView);
5658
- if (this.lastContainer) {
5659
- const prevOverflow = this.lastContainer.style.overflow;
5660
- const newOverflow = computed$1 >= this.maxHeightValue - 1 ? "auto" : "hidden";
5661
- if (prevOverflow !== newOverflow) {
5662
- this.lastContainer.style.overflow = newOverflow;
5663
- if (newOverflow === "auto" && this.shouldAutoScroll) this.maybeScrollToBottom();
5664
- }
5665
- }
5781
+ this.dlog("content-size-change syncing height/reveal");
5782
+ this.syncHeightAndRevealAfterContentChange();
5666
5783
  } catch (err) {
5667
5784
  error("EditorManager", "content-size-change error", err);
5668
5785
  }
@@ -5730,6 +5847,11 @@ var EditorManager = class {
5730
5847
  if (target !== -1 && this.editorHeightManager) await this.waitForHeightApplied(target, 500);
5731
5848
  else await new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(() => r())));
5732
5849
  this.dlog("running delayed immediate reveal", "ticket=", ticket, "line=", line);
5850
+ if (ticket !== this.revealTicket) {
5851
+ this.dlog("delayed immediate reveal skipped, stale ticket", ticket, "current", this.revealTicket);
5852
+ return;
5853
+ }
5854
+ this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5733
5855
  this.performImmediateReveal(line, ticket);
5734
5856
  } catch (err) {
5735
5857
  error("EditorManager", "scheduleImmediateRevealAfterLayout error", err);
@@ -5738,20 +5860,33 @@ var EditorManager = class {
5738
5860
  }
5739
5861
  waitForHeightApplied(target, timeoutMs = 500) {
5740
5862
  return new Promise((resolve) => {
5863
+ var _this$editorHeightMan6, _this$editorHeightMan7;
5741
5864
  const start = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
5865
+ const tolerance = this.getHeightChangeTolerancePx();
5866
+ 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;
5867
+ let settled = false;
5868
+ const resolveAfterSettle = () => {
5869
+ if (settled) return;
5870
+ settled = true;
5871
+ if (transitionMs > 0) {
5872
+ setTimeout(resolve, transitionMs);
5873
+ return;
5874
+ }
5875
+ requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
5876
+ };
5742
5877
  const check = () => {
5743
5878
  try {
5744
- var _this$editorHeightMan3, _this$editorHeightMan4;
5745
- 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;
5746
- if (last !== -1 && Math.abs(last - target) <= 12) {
5879
+ var _this$editorHeightMan8, _this$editorHeightMan9;
5880
+ 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;
5881
+ if (last !== -1 && Math.abs(last - target) <= tolerance) {
5747
5882
  this.dlog("waitForHeightApplied satisfied", last, "target=", target);
5748
- resolve();
5883
+ resolveAfterSettle();
5749
5884
  return;
5750
5885
  }
5751
5886
  const now = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
5752
5887
  if (now - start > timeoutMs) {
5753
5888
  log("EditorManager", "waitForHeightApplied timeout", last, "target=", target);
5754
- resolve();
5889
+ resolveAfterSettle();
5755
5890
  return;
5756
5891
  }
5757
5892
  } catch {}
@@ -5803,12 +5938,7 @@ var EditorManager = class {
5803
5938
  const newLineCount$1 = model.getLineCount();
5804
5939
  this.cachedLineCount = newLineCount$1;
5805
5940
  this.cachedComputedHeight = null;
5806
- if (newLineCount$1 !== prevLineCount$1) {
5807
- const shouldImmediate = this.shouldPerformImmediateReveal();
5808
- if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5809
- const computed$1 = this.syncNonOverflowingLayout();
5810
- if (computed$1 != null && computed$1 >= this.maxHeightValue - 1) this.forceReveal(newLineCount$1);
5811
- }
5941
+ if (newLineCount$1 !== prevLineCount$1) this.syncHeightAndRevealAfterContentChange(newLineCount$1);
5812
5942
  return;
5813
5943
  }
5814
5944
  let prevCode;
@@ -5838,13 +5968,7 @@ var EditorManager = class {
5838
5968
  const newLineCount = model.getLineCount();
5839
5969
  this.cachedLineCount = newLineCount;
5840
5970
  this.cachedComputedHeight = null;
5841
- if (newLineCount !== prevLineCount) {
5842
- const shouldImmediate = this.shouldPerformImmediateReveal();
5843
- if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5844
- this.syncNonOverflowingLayout();
5845
- if (shouldImmediate) this.scheduleImmediateRevealAfterLayout(newLineCount);
5846
- else this.maybeScrollToBottom(newLineCount);
5847
- }
5971
+ if (newLineCount !== prevLineCount) this.syncHeightAndRevealAfterContentChange(newLineCount);
5848
5972
  }
5849
5973
  appendCode(appendText, codeLanguage) {
5850
5974
  if (!this.editorView) return;
@@ -5876,10 +6000,7 @@ var EditorManager = class {
5876
6000
  this.lastKnownCode = next;
5877
6001
  const newLineCount = model.getLineCount();
5878
6002
  this.cachedLineCount = newLineCount;
5879
- if (newLineCount !== prevLineCount) {
5880
- this.syncNonOverflowingLayout();
5881
- this.maybeScrollToBottom(newLineCount);
5882
- }
6003
+ if (newLineCount !== prevLineCount) this.syncHeightAndRevealAfterContentChange(newLineCount);
5883
6004
  return;
5884
6005
  }
5885
6006
  const res = computeMinimalEdit(prev, next);
@@ -5932,13 +6053,7 @@ var EditorManager = class {
5932
6053
  if (lastLine !== newLineCount) {
5933
6054
  this.cachedLineCount = newLineCount;
5934
6055
  this.cachedComputedHeight = null;
5935
- const shouldImmediate = this.shouldPerformImmediateReveal();
5936
- if (shouldImmediate) this.suppressScrollWatcher(this.scrollWatcherSuppressionMs);
5937
- this.syncNonOverflowingLayout();
5938
- if (shouldImmediate) try {
5939
- this.forceReveal(newLineCount);
5940
- } catch {}
5941
- else this.maybeScrollToBottom(newLineCount);
6056
+ this.syncHeightAndRevealAfterContentChange(newLineCount);
5942
6057
  }
5943
6058
  }
5944
6059
  setLanguage(language, languages$1) {
@@ -5953,8 +6068,8 @@ var EditorManager = class {
5953
6068
  return this.editorView;
5954
6069
  }
5955
6070
  getCode() {
5956
- var _this$editorView12;
5957
- 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;
6071
+ var _this$editorView15;
6072
+ 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;
5958
6073
  }
5959
6074
  setUpdateThrottleMs(ms) {
5960
6075
  this.updateThrottleMs = ms;
@@ -5975,6 +6090,8 @@ var EditorManager = class {
5975
6090
  }
5976
6091
  this.lastKnownCode = null;
5977
6092
  if (this.lastContainer) {
6093
+ if (this.previousScrollbarGutter != null) this.lastContainer.style.scrollbarGutter = this.previousScrollbarGutter;
6094
+ this.previousScrollbarGutter = null;
5978
6095
  this.lastContainer.style.minHeight = "";
5979
6096
  this.lastContainer.innerHTML = "";
5980
6097
  this.lastContainer = null;
@@ -5999,6 +6116,8 @@ var EditorManager = class {
5999
6116
  this._hasScrollBar = false;
6000
6117
  this.shouldAutoScroll = !!this.autoScrollInitial;
6001
6118
  this.lastScrollTop = 0;
6119
+ if (this.lastContainer && this.previousScrollbarGutter != null) this.lastContainer.style.scrollbarGutter = this.previousScrollbarGutter;
6120
+ this.previousScrollbarGutter = null;
6002
6121
  if (this.editorHeightManager) {
6003
6122
  this.editorHeightManager.dispose();
6004
6123
  this.editorHeightManager = null;
@@ -6305,7 +6424,7 @@ let globalAppliedThemeName = null;
6305
6424
  * @param {MonacoLanguage[]} [monacoOptions.languages] - 支持的编程语言数组
6306
6425
  * @param {string} [monacoOptions.theme] - 初始主题名称
6307
6426
  * @param {boolean} [monacoOptions.isCleanOnBeforeCreate] - 是否在创建前清理之前注册的资源, 默认为 true
6308
- * @param {(monaco: typeof import('monaco-editor')) => monaco.IDisposable[]} [monacoOptions.onBeforeCreate] - 编辑器创建前的钩子函数
6427
+ * @param {(monaco: typeof import('monaco-editor/esm/vs/editor/editor.api')) => monaco.IDisposable[]} [monacoOptions.onBeforeCreate] - 编辑器创建前的钩子函数
6309
6428
  *
6310
6429
  * @returns {{
6311
6430
  * 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.40",
5
- "packageManager": "pnpm@10.33.2",
4
+ "version": "0.0.42",
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
+ }