gesso-core 0.8.0 → 0.8.1

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.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as UiPlatformAdapter, $a as boxShadowArraysEqual, $i as UiKeyboardEvent, $n as isVideoSurface, $r as pathValuesEqual, $t as textRunDecorations, A as formatNumber, Aa as withDensity, Ai as propertyValuesEqual, An as isPressable, Ao as colorsEqual, Ar as resolveString, At as paragraphGeometryFrom, B as MAX_MEASURES_PER_CHILD, Ba as contrastRatio, Bi as writeOverrideProperty, Bn as CARET_BLINK_MS, Bo as easings, Br as UiProperties, Bt as isPrintable, C as LayoutEngine, Ca as bandOf, Ci as borderRadiusCorners, Cn as selectionRangeOf, Co as colorsEqualPalette, Cr as wordRangeAt, Ct as scrollbarThumbs, D as describeOverrides, Da as lightTheme, Di as normalizeBorderRadius, Dn as isNodeInert, Do as colorToHex, Dr as resolveNumber, Dt as hasDrawnText, E as describeLength, Ea as darkTheme, Ei as borderRadiusValuesEqual, En as isNodeHitTestable, Eo as UiBasicColors, Er as resolveBoolean, Et as UiInputDispatcher, F as LayoutRecord, Fa as hasThemeExtension, Fi as DirtyNodeSet, Fn as hasTextLinks, Fo as createEnvironmentKey, Fr as inheritedPropertyNames, Ft as comparePositions, G as sizeGridTracks, Ga as defaultSpacing, Gi as visualStatesEqual, Gn as editorOf, Gr as normalizeStates, Gt as drawText, H as FlexDirection, Ha as raiseContrast, Hi as defaultVisualState, Hn as EDITOR_PROP, Ho as steps, Hr as UI_SEMANTIC_STATES, Ht as applyCanvasTextStyle, I as Constraints, Ia as noThemeExtensions, Ii as clearOverrideProperty, In as linkHoverOf, Io as findEnvironmentKey, Ir as propertyEffects, It as edgeField, J as MainAxisAlignment, Ja as spacingSteps, Ji as UiCompositionEvent, Jn as isReadOnly, Jr as validateStates, Jt as runCanvasStyleInto, K as AlignContent, Ka as scaleSpacing, Ki as MOUSE_POINTER, Kn as isEditableNode, Kr as statesEqual, Kt as fillTextRects, L as clampSize, La as themeExtension, Li as overrideSources, Ln as linkOf, Lo as provided, Lr as propertyIsInherited, Lt as editingGroupOf, M as withOverrideSource, Ma as lengths, Mi as withPointer, Mn as pointerEventsOf, Mo as parseColor, Mr as findPropertyDefinition, Mt as wordRangeIn, N as accumulatedOffsetTo, Na as unitsEqual, Ni as UiEnvironment, Nn as resolveCursor, No as rgb8, Nr as getPropertyNames, Nt as textInputOf, O as formatConstraints, Oa as themesEqual, Oi as uniformBorderRadius, On as isNodeSelectable, Oo as colorToRgba, Or as resolveProperty, Ot as offsetAtPointIn, P as contentOffset, Pa as defineThemeExtension, Pi as UiNode, Pn as clearLinkHover, Po as rgba, Pr as inheritedPropertyFlags, Pt as adjacentField, Q as CanvasPlatformSurface, Qa as boxShadow, Qi as UiInputEvent, Qn as resolveColorValue, Qr as paintValuesEqual, Qt as textRunBackgrounds, R as constraintsEqual, Ra as themeExtensionsEqual, Ri as resetOverrideWarnings, Rn as linkRunAtPointIn, Ro as cubicBezier, Rr as propertyNarrowers, Rt as commandForKey, S as tracePathData, Sa as UiContainerSizeSource, Si as borderRadius, Sn as selectableTextOf, So as textStylesEqual, Sr as previousWordStart, St as scrollbarThumb, T as SCROLLBAR_LINGER_MS, Ta as unknownContainerSize, Ti as borderRadiusIsZero, Tn as isNodeFocusable, To as lightColors, Tr as DEFAULT_LINE_HEIGHT_FACTOR, Tt as scrollsFromRight, U as parseFlexDirection, Ua as relativeLuminance, Ui as hasVisualState, Un as caretVisibleAt, Ur as isUiRole, Ut as buildFontString, V as isLayoutProtocol, Va as highContrastColors, Vi as UiVisualState, Vn as CARET_WIDTH, Vo as linear, Vr as UI_ROLES, Vt as EditableLayout, W as placeGridItems, Wa as densityFactors, Wi as visualState, Wn as editorFor, Wr as isUiSemanticState, Wt as createCanvasTextStyle, X as parseCrossAxisAlignment, Xa as shadowsEqual, Xi as UiFocusEvent, Xn as nextCaretToggle, Xr as validateSubgrid, Xt as spanOf, Y as parseAlignContent, Ya as defaultShadows, Yi as UiEventType, Yn as maskText, Yr as UI_SUBGRID_AXES, Yt as runFontString, Z as parseMainAxisAlignment, Za as BOX_SHADOW_BLUR_REACH, Zi as UiGestureEvent, Zn as syncEditorValue, Zr as inputsEqual, Zt as textMeasureRequest, _ as paintsAfterChildren, _a as springIn, _i as minmax, _n as matchRangesOf, _o as spanAtOffset, _r as lineEndAt, _t as SCROLLBAR_MIN_THUMB, a as layerRegion, aa as UiWheelDeltaMode, ai as MAX_GRADIENT_STOPS, an as DEFAULT_FONT_SIZE, ao as shadowsOf, ar as layoutParagraph, at as UiEditingController, b as labelOrigin, ba as noInsets, bi as resolveLength, bn as clearSelectionRange, bo as textContentOf, br as nextWordEnd, bt as scrollLeaderOf, c as paintPictures, ca as wheelDeltaYOf, ci as linearGradient, cn as colorToCss, co as shapesEqual, cr as lineIndexAtY, ct as UiPinchRecognizer, d as PaintRecorder, da as UiBinding, di as auto, dn as isPaintVisible, do as typographyEqual, dr as offsetAtPoint, dt as UiKeyboardController, ea as UiPasteEvent, ei as UiTransforms, en as bumpFontStack, eo as boxShadowRadius, er as videoFrameSize, et as capturePointer, f as replayPaint, fa as UiEnvironmentKeys, fi as fr, fn as normalizeTextAlign, fo as defaultTextStyle, fr as offsetAtX, ft as UiPointerController, g as hasDecorationPhase, ga as easingIn, gi as isPercentLength, gn as clearMatchRanges, go as resolvedSpansOf, gr as graphemeBoundaries, gt as SCROLLBAR_INSET, h as decorationRect, ha as durationIn, hi as isMinMaxTrack, hn as TEXT_MATCHES_PROP, ho as hiddenRangesOf, hr as EditableTextModel, ht as SCROLLBAR_HOVER_ZONE, i as traceRoundedRect, ia as UiTextChangeEvent, ii as transformsEqual, in as DEFAULT_FONT_FAMILY, io as fittedShadowRadius, ir as ELLIPSIS, it as touchActionFor, j as labelNode, ja as defaultUnits, ji as TOUCH_TARGET, jn as isSubtreeInert, jo as normalizeColor, jr as closestPropertyName, jt as selectionRectsIn, k as formatExplanation, ka as withContrast, ki as defineProperty, kn as isNodeTabStop, ko as colorValuesEqual, kr as resolvePropertyByName, kt as paragraphGeometry, l as PaintTarget, la as UiNodeType, li as radialGradient, ln as computeObjectFitRect, lo as defaultTypography, lr as lineIndexForOffset, lt as UiWheelController, m as decorationColor, ma as defineMotion, mi as isFrLength, mn as resolvePaintState, mo as flattenTextSpans, mr as selectionRects, mt as UiHitTester, n as createCanvasSurface, na as UiPointerEvent, ni as transform, nn as fontStackFor, no as boxShadowValuesEqual, nr as ParagraphTextMeasurer, nt as pointerDeviceOf, o as opacityNeedsLayer, oa as UiWheelEvent, oi as gradientPaint, on as DEFAULT_FONT_WEIGHT, oo as defaultShapes, or as proportionalFontMetrics, ot as UiTouchScroller, p as ScaledImageCache, pa as defaultMotion, pi as isAutoLength, pn as normalizeVerticalAlign, po as editableSpansOf, pr as offsetForVerticalMove, pt as UiFocusManager, q as CrossAxisAlignment, qa as spacingEqual, qi as UiBeforeInputEvent, qn as isMultiline, qr as validateRole, qt as layoutTextLines, r as Canvas2DRenderer, ra as UiSelectionChangeEvent, ri as transformIsIdentity, rn as registerFontStack, ro as boxShadowsEqual, rr as spannedRunsFor, rt as prepareInputSurface, s as PaintPictureCache, sa as noKeyModifiers, si as gradientsEqual, sn as DEFAULT_TEXT_COLOR, so as isShapeName, sr as caretRectFor, st as UiGestureRecognizer, t as CanvasSurface, ta as UiPinchEvent, ti as parseTransform, tn as clearFontStacks, to as boxShadowReach, tr as CharacterCountTextMeasurer, tt as isImeKey, u as EMPTY_RECORDING, ua as DirtyFlags, ui as validateGradient, un as createPaintState, uo as isTypographyRole, ur as lineLimit, ut as isScrollContainer, v as LABEL_PADDING_X, va as UiInsetRegistry, vi as percent, vn as setMatchRanges, vo as spannedTextOf, vr as lineStartAt, vt as SCROLLBAR_THICKNESS, w as SCROLLBAR_FADE_MS, wa as containerBands, wi as borderRadiusEqual, wn as setSelectionRange, wo as darkColors, wr as UiGraph, wt as scrollbarZoneAt, x as snapScroll, xa as observeViewportInsets, xi as UiBorderRadiuses, xn as selectableTextNodes, xo as textSpansEqual, xr as previousGraphemeStart, xt as scrollRange, y as drawOverlayShapes, ya as insetsEqual, yi as repeat, yn as TEXT_SELECTION_PROP, yo as spansDifferOnlyInPaint, yr as nextGraphemeEnd, yt as scrollBounds, z as tightenConstraints, za as withThemeExtension, zi as writeDeclaredProperty, zn as setLinkHover, zo as easingCss, zr as propertyValuesEqualByName, zt as detectEditingPlatform } from "./CanvasSurface-Cy2UErXI.js";
1
+ import { $ as UiPlatformAdapter, $a as boxShadowArraysEqual, $i as UiKeyboardEvent, $n as isVideoSurface, $r as pathValuesEqual, $t as textRunDecorations, A as formatNumber, Aa as withDensity, Ai as propertyValuesEqual, An as isPressable, Ao as colorsEqual, Ar as resolveString, At as paragraphGeometryFrom, B as MAX_MEASURES_PER_CHILD, Ba as contrastRatio, Bi as writeOverrideProperty, Bn as CARET_BLINK_MS, Bo as easings, Br as UiProperties, Bt as isPrintable, C as LayoutEngine, Ca as bandOf, Ci as borderRadiusCorners, Cn as selectionRangeOf, Co as colorsEqualPalette, Cr as wordRangeAt, Ct as scrollbarThumbs, D as describeOverrides, Da as lightTheme, Di as normalizeBorderRadius, Dn as isNodeInert, Do as colorToHex, Dr as resolveNumber, Dt as hasDrawnText, E as describeLength, Ea as darkTheme, Ei as borderRadiusValuesEqual, En as isNodeHitTestable, Eo as UiBasicColors, Er as resolveBoolean, Et as UiInputDispatcher, F as LayoutRecord, Fa as hasThemeExtension, Fi as DirtyNodeSet, Fn as hasTextLinks, Fo as createEnvironmentKey, Fr as inheritedPropertyNames, Ft as comparePositions, G as sizeGridTracks, Ga as defaultSpacing, Gi as visualStatesEqual, Gn as editorOf, Gr as normalizeStates, Gt as drawText, H as FlexDirection, Ha as raiseContrast, Hi as defaultVisualState, Hn as EDITOR_PROP, Ho as steps, Hr as UI_SEMANTIC_STATES, Ht as applyCanvasTextStyle, I as Constraints, Ia as noThemeExtensions, Ii as clearOverrideProperty, In as linkHoverOf, Io as findEnvironmentKey, Ir as propertyEffects, It as edgeField, J as MainAxisAlignment, Ja as spacingSteps, Ji as UiCompositionEvent, Jn as isReadOnly, Jr as validateStates, Jt as runCanvasStyleInto, K as AlignContent, Ka as scaleSpacing, Ki as MOUSE_POINTER, Kn as isEditableNode, Kr as statesEqual, Kt as fillTextRects, L as clampSize, La as themeExtension, Li as overrideSources, Ln as linkOf, Lo as provided, Lr as propertyIsInherited, Lt as editingGroupOf, M as withOverrideSource, Ma as lengths, Mi as withPointer, Mn as pointerEventsOf, Mo as parseColor, Mr as findPropertyDefinition, Mt as wordRangeIn, N as accumulatedOffsetTo, Na as unitsEqual, Ni as UiEnvironment, Nn as resolveCursor, No as rgb8, Nr as getPropertyNames, Nt as textInputOf, O as formatConstraints, Oa as themesEqual, Oi as uniformBorderRadius, On as isNodeSelectable, Oo as colorToRgba, Or as resolveProperty, Ot as offsetAtPointIn, P as contentOffset, Pa as defineThemeExtension, Pi as UiNode, Pn as clearLinkHover, Po as rgba, Pr as inheritedPropertyFlags, Pt as adjacentField, Q as CanvasPlatformSurface, Qa as boxShadow, Qi as UiInputEvent, Qn as resolveColorValue, Qr as paintValuesEqual, Qt as textRunBackgrounds, R as constraintsEqual, Ra as themeExtensionsEqual, Ri as resetOverrideWarnings, Rn as linkRunAtPointIn, Ro as cubicBezier, Rr as propertyNarrowers, Rt as commandForKey, S as tracePathData, Sa as UiContainerSizeSource, Si as borderRadius, Sn as selectableTextOf, So as textStylesEqual, Sr as previousWordStart, St as scrollbarThumb, T as SCROLLBAR_LINGER_MS, Ta as unknownContainerSize, Ti as borderRadiusIsZero, Tn as isNodeFocusable, To as lightColors, Tr as DEFAULT_LINE_HEIGHT_FACTOR, Tt as scrollsFromRight, U as parseFlexDirection, Ua as relativeLuminance, Ui as hasVisualState, Un as caretVisibleAt, Ur as isUiRole, Ut as buildFontString, V as isLayoutProtocol, Va as highContrastColors, Vi as UiVisualState, Vn as CARET_WIDTH, Vo as linear, Vr as UI_ROLES, Vt as EditableLayout, W as placeGridItems, Wa as densityFactors, Wi as visualState, Wn as editorFor, Wr as isUiSemanticState, Wt as createCanvasTextStyle, X as parseCrossAxisAlignment, Xa as shadowsEqual, Xi as UiFocusEvent, Xn as nextCaretToggle, Xr as validateSubgrid, Xt as spanOf, Y as parseAlignContent, Ya as defaultShadows, Yi as UiEventType, Yn as maskText, Yr as UI_SUBGRID_AXES, Yt as runFontString, Z as parseMainAxisAlignment, Za as BOX_SHADOW_BLUR_REACH, Zi as UiGestureEvent, Zn as syncEditorValue, Zr as inputsEqual, Zt as textMeasureRequest, _ as paintsAfterChildren, _a as springIn, _i as minmax, _n as matchRangesOf, _o as spanAtOffset, _r as lineEndAt, _t as SCROLLBAR_MIN_THUMB, a as layerRegion, aa as UiWheelDeltaMode, ai as MAX_GRADIENT_STOPS, an as DEFAULT_FONT_SIZE, ao as shadowsOf, ar as layoutParagraph, at as UiEditingController, b as labelOrigin, ba as noInsets, bi as resolveLength, bn as clearSelectionRange, bo as textContentOf, br as nextWordEnd, bt as scrollLeaderOf, c as paintPictures, ca as wheelDeltaYOf, ci as linearGradient, cn as colorToCss, co as shapesEqual, cr as lineIndexAtY, ct as UiPinchRecognizer, d as PaintRecorder, da as UiBinding, di as auto, dn as isPaintVisible, do as typographyEqual, dr as offsetAtPoint, dt as UiKeyboardController, ea as UiPasteEvent, ei as UiTransforms, en as bumpFontStack, eo as boxShadowRadius, er as videoFrameSize, et as capturePointer, f as replayPaint, fa as UiEnvironmentKeys, fi as fr, fn as normalizeTextAlign, fo as defaultTextStyle, fr as offsetAtX, ft as UiPointerController, g as hasDecorationPhase, ga as easingIn, gi as isPercentLength, gn as clearMatchRanges, go as resolvedSpansOf, gr as graphemeBoundaries, gt as SCROLLBAR_INSET, h as decorationRect, ha as durationIn, hi as isMinMaxTrack, hn as TEXT_MATCHES_PROP, ho as hiddenRangesOf, hr as EditableTextModel, ht as SCROLLBAR_HOVER_ZONE, i as traceRoundedRect, ia as UiTextChangeEvent, ii as transformsEqual, in as DEFAULT_FONT_FAMILY, io as fittedShadowRadius, ir as ELLIPSIS, it as touchActionFor, j as labelNode, ja as defaultUnits, ji as TOUCH_TARGET, jn as isSubtreeInert, jo as normalizeColor, jr as closestPropertyName, jt as selectionRectsIn, k as formatExplanation, ka as withContrast, ki as defineProperty, kn as isNodeTabStop, ko as colorValuesEqual, kr as resolvePropertyByName, kt as paragraphGeometry, l as PaintTarget, la as UiNodeType, li as radialGradient, ln as computeObjectFitRect, lo as defaultTypography, lr as lineIndexForOffset, lt as UiWheelController, m as decorationColor, ma as defineMotion, mi as isFrLength, mn as resolvePaintState, mo as flattenTextSpans, mr as selectionRects, mt as UiHitTester, n as createCanvasSurface, na as UiPointerEvent, ni as transform, nn as fontStackFor, no as boxShadowValuesEqual, nr as ParagraphTextMeasurer, nt as pointerDeviceOf, o as opacityNeedsLayer, oa as UiWheelEvent, oi as gradientPaint, on as DEFAULT_FONT_WEIGHT, oo as defaultShapes, or as proportionalFontMetrics, ot as UiTouchScroller, p as ScaledImageCache, pa as defaultMotion, pi as isAutoLength, pn as normalizeVerticalAlign, po as editableSpansOf, pr as offsetForVerticalMove, pt as UiFocusManager, q as CrossAxisAlignment, qa as spacingEqual, qi as UiBeforeInputEvent, qn as isMultiline, qr as validateRole, qt as layoutTextLines, r as Canvas2DRenderer, ra as UiSelectionChangeEvent, ri as transformIsIdentity, rn as registerFontStack, ro as boxShadowsEqual, rr as spannedRunsFor, rt as prepareInputSurface, s as PaintPictureCache, sa as noKeyModifiers, si as gradientsEqual, sn as DEFAULT_TEXT_COLOR, so as isShapeName, sr as caretRectFor, st as UiGestureRecognizer, t as CanvasSurface, ta as UiPinchEvent, ti as parseTransform, tn as clearFontStacks, to as boxShadowReach, tr as CharacterCountTextMeasurer, tt as isImeKey, u as EMPTY_RECORDING, ua as DirtyFlags, ui as validateGradient, un as createPaintState, uo as isTypographyRole, ur as lineLimit, ut as isScrollContainer, v as LABEL_PADDING_X, va as UiInsetRegistry, vi as percent, vn as setMatchRanges, vo as spannedTextOf, vr as lineStartAt, vt as SCROLLBAR_THICKNESS, w as SCROLLBAR_FADE_MS, wa as containerBands, wi as borderRadiusEqual, wn as setSelectionRange, wo as darkColors, wr as UiGraph, wt as scrollbarZoneAt, x as snapScroll, xa as observeViewportInsets, xi as UiBorderRadiuses, xn as selectableTextNodes, xo as textSpansEqual, xr as previousGraphemeStart, xt as scrollRange, y as drawOverlayShapes, ya as insetsEqual, yi as repeat, yn as TEXT_SELECTION_PROP, yo as spansDifferOnlyInPaint, yr as nextGraphemeEnd, yt as scrollBounds, z as tightenConstraints, za as withThemeExtension, zi as writeDeclaredProperty, zn as setLinkHover, zo as easingCss, zr as propertyValuesEqualByName, zt as detectEditingPlatform } from "./CanvasSurface-CkRHlmpu.js";
2
2
  import { BehaviorSubject, EMPTY, Subject, combineLatest, distinctUntilChanged, isObservable as isObservable$1, map, of } from "rxjs";
3
3
  //#region src/animation/Interpolate.ts
4
4
  const interpolateNumber = (from, to, t) => from + (to - from) * t;
@@ -2558,7 +2558,16 @@ var UiGraphBuilder = class {
2558
2558
  this.graph.insertBefore(parent, anchor, cursor);
2559
2559
  } else {
2560
2560
  matched.add(anchor);
2561
- if (this.reconciledFrom.get(anchor) === element) return anchor;
2561
+ const previous = this.reconciledFrom.get(anchor);
2562
+ if (previous === element) return anchor;
2563
+ if (previous !== void 0 && isComponentLikeElement(previous) && previous.component !== element.component) {
2564
+ resolver.release(anchorId);
2565
+ for (let child = anchor.firstChild; child !== null;) {
2566
+ const next = child.nextSibling;
2567
+ this.removeSubtree(child);
2568
+ child = next;
2569
+ }
2570
+ }
2562
2571
  }
2563
2572
  this.reconcileChildren(anchor, [resolver.resolve(element, anchorId, anchor)]);
2564
2573
  this.reconciledFrom.set(anchor, element);
@@ -16378,6 +16387,12 @@ const MAX_CADENCE_MS = 50;
16378
16387
  const WATCH_REFRESHES = 2;
16379
16388
  const IDLE_TICKS_BEFORE_STOP = 4;
16380
16389
  /**
16390
+ * How long a frame waits for this thread's own refresh before a timer
16391
+ * draws it instead; see `watchLocal`. Far longer than any display's
16392
+ * refresh, so it never stands in for one that is coming.
16393
+ */
16394
+ const LOCAL_WATCH_MS = 250;
16395
+ /**
16381
16396
  * Timer-backed clock that works in the browser main thread,
16382
16397
  * in a Worker, and in Node.
16383
16398
  */
@@ -16491,6 +16506,8 @@ const MAX_QUEUED_REFRESHES = 8;
16491
16506
  const RETRY_LOCAL_MS = 2e3;
16492
16507
  /** The most refreshes a frame is given: two, sixty at 120 Hz; slower than that is no smoother. */
16493
16508
  const MAX_STRIDE = 2;
16509
+ /** How many times faster than the display measured at start a refined beat may read before it is not believed. */
16510
+ const MAX_STRIDE_OFF = 4;
16494
16511
  function localAnimationFrame() {
16495
16512
  const host = globalThis;
16496
16513
  return typeof host.requestAnimationFrame === "function" ? host.requestAnimationFrame.bind(host) : null;
@@ -16536,6 +16553,10 @@ var UiHostFrameClock = class {
16536
16553
  /** This thread's own `requestAnimationFrame`, or null where there is none. */
16537
16554
  local;
16538
16555
  localHandle = null;
16556
+ /** This thread's own refreshes so far, which `watchLocal` counts on. */
16557
+ localRefreshes = 0;
16558
+ /** The timer standing by for a refresh that does not come; see `watchLocal`. */
16559
+ localWatch = null;
16539
16560
  /** Whether the page is hidden, when this thread's refreshes do not come. */
16540
16561
  hidden = false;
16541
16562
  timeOrigin;
@@ -16588,8 +16609,10 @@ var UiHostFrameClock = class {
16588
16609
  this.armTimer();
16589
16610
  return;
16590
16611
  }
16612
+ this.watchLocal();
16591
16613
  if (this.localHandle === null) this.localHandle = this.local((time) => {
16592
16614
  this.localHandle = null;
16615
+ this.localRefreshes++;
16593
16616
  this.recordLocal(time);
16594
16617
  if (this.pending) {
16595
16618
  const started = this.now();
@@ -16603,6 +16626,42 @@ var UiHostFrameClock = class {
16603
16626
  this.armTimer();
16604
16627
  }
16605
16628
  /**
16629
+ * Draws a wanted frame on a timer when this thread's own refreshes
16630
+ * have stopped coming on a page that says it is shown.
16631
+ *
16632
+ * They do stop. A window that is shown but not composited (a browser
16633
+ * pane hidden inside a desktop app, a window behind others on some
16634
+ * systems) refreshes a page once a second or not at all, while
16635
+ * `document.visibilityState` stays `visible`, so `setHidden` never
16636
+ * hears of it; and a worker whose canvas the compositor is behind on
16637
+ * is not given another refresh until it catches up. A frame asked for
16638
+ * then waited for a refresh that did not come, and with no timer on
16639
+ * this path, nothing else drew it: the application stopped answering,
16640
+ * with its last frame on screen.
16641
+ *
16642
+ * One timer, a quarter of a second long, armed while frames are wanted
16643
+ * and never more than one: it draws a frame only when not one refresh
16644
+ * came in the whole of it. A compositor that is answering, however
16645
+ * slowly the frames themselves run, always beats it, so it never
16646
+ * stands in for a refresh that is coming (see the spec about a blocked
16647
+ * host thread); it costs four wake-ups a second while something
16648
+ * animates, against one per refresh for a per-frame watch.
16649
+ */
16650
+ watchLocal() {
16651
+ if (this.localWatch !== null) return;
16652
+ const seen = this.localRefreshes;
16653
+ this.localWatch = setTimeout(() => {
16654
+ this.localWatch = null;
16655
+ if (!this.pending || this.local === null) return;
16656
+ if (this.localRefreshes === seen) {
16657
+ this.localHandle = null;
16658
+ this.deliver(this.now());
16659
+ if (!this.pending) return;
16660
+ }
16661
+ this.watchLocal();
16662
+ }, LOCAL_WATCH_MS);
16663
+ }
16664
+ /**
16606
16665
  * The page was hidden or shown. While it is hidden this thread's own
16607
16666
  * refreshes stop, so a frame asked for is paced by the timer, as a
16608
16667
  * hosted clock is when its host stops ticking; one already waiting
@@ -16735,6 +16794,7 @@ var UiHostFrameClock = class {
16735
16794
  const cadence = this.cadenceMs();
16736
16795
  let interval = cadence !== null && Math.abs(cadence - this.display.interval) > this.display.interval * NEW_DISPLAY ? cadence : this.display.interval;
16737
16796
  for (let pass = 0; pass < BEAT_PASSES; pass++) interval = this.refineInterval(interval);
16797
+ if (!(interval >= this.display.interval / MAX_STRIDE_OFF && interval <= MAX_CADENCE_MS)) interval = this.display.interval;
16738
16798
  const latest = this.refreshes[this.refreshes.length - 1];
16739
16799
  let earliest = Infinity;
16740
16800
  for (const time of this.refreshes) {
@@ -16780,7 +16840,8 @@ var UiHostFrameClock = class {
16780
16840
  deliverOnBeat(time) {
16781
16841
  const beat = this.beat();
16782
16842
  let refresh = time - ((time - beat.start) % beat.interval + beat.interval) % beat.interval;
16783
- while (refresh < this.lastLocked + (this.stride - .5) * beat.interval) refresh += beat.interval;
16843
+ const after = this.lastLocked + (this.stride - .5) * beat.interval;
16844
+ if (refresh < after) refresh += Math.ceil((after - refresh) / beat.interval) * beat.interval;
16784
16845
  this.lastLocked = refresh;
16785
16846
  this.refreshesSinceFrame = 0;
16786
16847
  const started = this.now();
@@ -16916,8 +16977,37 @@ var UiHostFrameClock = class {
16916
16977
  const cadence = this.cadenceMs();
16917
16978
  return cadence === null ? this.fallbackMs : Math.max(1, Math.min(this.fallbackMs, cadence));
16918
16979
  }
16980
+ /**
16981
+ * Draws the pending frame now, on this clock's timeline, and nothing
16982
+ * when none is pending (`FrameService.flush`): for a tool that changed
16983
+ * the screen and must read it drawn, in a window that may be sent no
16984
+ * refreshes. It is not a refresh, so it teaches the clock nothing about
16985
+ * the display. Handed to `tick` as one, with this thread's time, which
16986
+ * is not the host's, it took the beat backwards; see `tick`.
16987
+ */
16988
+ flush() {
16989
+ if (this.pending) this.drawNow();
16990
+ }
16991
+ /**
16992
+ * Draws the pending frame now, without waiting for a refresh: on the
16993
+ * display's beat when frames are timed on it, so its time is the next
16994
+ * refresh's and never one already drawn for; else at this moment, on
16995
+ * the timeline the clock's frames are on.
16996
+ */
16997
+ drawNow() {
16998
+ this.clearFallback();
16999
+ if (this.locked && this.display !== null && this.refreshes.length > 0 && this.lastTickTime !== null) {
17000
+ this.deliverOnBeat(this.lastTickTime);
17001
+ return;
17002
+ }
17003
+ this.deliver(this.local !== null ? this.now() : this.hostTime());
17004
+ }
16919
17005
  cancelFrame() {
16920
17006
  this.pending = false;
17007
+ if (this.localWatch !== null) {
17008
+ clearTimeout(this.localWatch);
17009
+ this.localWatch = null;
17010
+ }
16921
17011
  this.clearFallback();
16922
17012
  if (this.local === null) this.setActive(false);
16923
17013
  }
@@ -16937,11 +17027,19 @@ var UiHostFrameClock = class {
16937
17027
  * it is needed rather than negotiating every frame.
16938
17028
  */
16939
17029
  tick(time) {
17030
+ const backwards = this.lastTickTime !== null && time < this.lastTickTime;
17031
+ if (backwards && this.pending) {
17032
+ this.idleTicks = 0;
17033
+ this.drawNow();
17034
+ return;
17035
+ }
16940
17036
  this.hosted = true;
16941
17037
  this.stalled = false;
16942
- this.hostOffset = time - this.now();
16943
- this.recordCadence(time);
16944
- if (this.locked && this.display !== null) {
17038
+ if (!backwards) {
17039
+ this.hostOffset = time - this.now();
17040
+ this.recordCadence(time);
17041
+ }
17042
+ if (this.locked && this.display !== null && !backwards) {
16945
17043
  this.refreshes.push(time);
16946
17044
  if (this.refreshes.length > BEAT_SAMPLES) this.refreshes.shift();
16947
17045
  this.refreshesSinceFrame++;
@@ -16950,6 +17048,7 @@ var UiHostFrameClock = class {
16950
17048
  this.idleTicks = 0;
16951
17049
  const queued = this.now() - this.toLocal(time) > this.display.interval;
16952
17050
  if (this.refreshesSinceFrame >= this.stride && (!queued || this.refreshesSinceFrame >= MAX_QUEUED_REFRESHES)) this.deliverOnBeat(time);
17051
+ else this.armTimer();
16953
17052
  return;
16954
17053
  }
16955
17054
  }