@atlaskit/react-ufo 3.13.17 → 3.13.19

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/ssr/index.js +8 -2
  3. package/dist/cjs/vc/index.js +2 -0
  4. package/dist/cjs/vc/vc-observer/getVCRevisionDebugDetails.js +109 -11
  5. package/dist/cjs/vc/vc-observer/index.js +56 -43
  6. package/dist/cjs/vc/vc-observer/observers/index.js +4 -0
  7. package/dist/cjs/vc/vc-observer/observers/rll-placeholders/index.js +208 -0
  8. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +129 -16
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +16 -0
  10. package/dist/es2019/ssr/index.js +5 -1
  11. package/dist/es2019/vc/index.js +2 -0
  12. package/dist/es2019/vc/vc-observer/getVCRevisionDebugDetails.js +71 -9
  13. package/dist/es2019/vc/vc-observer/index.js +39 -22
  14. package/dist/es2019/vc/vc-observer/observers/index.js +4 -0
  15. package/dist/es2019/vc/vc-observer/observers/rll-placeholders/index.js +182 -0
  16. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +102 -11
  17. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +16 -0
  18. package/dist/esm/ssr/index.js +8 -2
  19. package/dist/esm/vc/index.js +2 -0
  20. package/dist/esm/vc/vc-observer/getVCRevisionDebugDetails.js +108 -11
  21. package/dist/esm/vc/vc-observer/index.js +56 -43
  22. package/dist/esm/vc/vc-observer/observers/index.js +4 -0
  23. package/dist/esm/vc/vc-observer/observers/rll-placeholders/index.js +201 -0
  24. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +130 -16
  25. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +16 -0
  26. package/dist/types/common/vc/types.d.ts +1 -1
  27. package/dist/types/ssr/index.d.ts +1 -0
  28. package/dist/types/vc/index.d.ts +1 -0
  29. package/dist/types/vc/vc-observer/getVCRevisionDebugDetails.d.ts +19 -18
  30. package/dist/types/vc/vc-observer/index.d.ts +7 -0
  31. package/dist/types/vc/vc-observer/observers/rll-placeholders/index.d.ts +49 -0
  32. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +7 -0
  33. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  34. package/dist/types-ts4.5/common/vc/types.d.ts +1 -1
  35. package/dist/types-ts4.5/ssr/index.d.ts +1 -0
  36. package/dist/types-ts4.5/vc/index.d.ts +1 -0
  37. package/dist/types-ts4.5/vc/vc-observer/getVCRevisionDebugDetails.d.ts +19 -18
  38. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +7 -0
  39. package/dist/types-ts4.5/vc/vc-observer/observers/rll-placeholders/index.d.ts +49 -0
  40. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +7 -0
  41. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  42. package/package.json +10 -1
@@ -2,6 +2,7 @@ export type FeatureFlagValue = boolean | string | number | Record<any, any>;
2
2
  export type ReportedTiming = {
3
3
  startTime: number;
4
4
  duration: number;
5
+ size?: number;
5
6
  };
6
7
  export type ReportedTimings = {
7
8
  [key: string]: ReportedTiming;
@@ -1,5 +1,6 @@
1
1
  import type { VCRawDataType, VCResult } from '../common/vc/types';
2
2
  import type { GetVCResultType, VCObserverInterface, VCObserverOptions } from './types';
3
+ export type { VCRevisionDebugDetails } from './vc-observer/getVCRevisionDebugDetails';
3
4
  declare global {
4
5
  var __vcObserver: VCObserverInterface;
5
6
  }
@@ -1,30 +1,31 @@
1
- import type { ComponentsLogType, VCEntryType } from '../../common/vc/types';
1
+ import type { ComponentsLogType, VCAbortReason, VCEntryType, VCIgnoreReason } from '../../common/vc/types';
2
2
  import type { VCObserverEntryType } from '../vc-observer-new/types';
3
- interface VCRevisionDebugDetails {
3
+ export type VCLogEntry = {
4
+ time: number;
5
+ viewportPercentage: number | null;
6
+ entries: Array<{
7
+ elementName: string;
8
+ type: VCObserverEntryType;
9
+ rect: DOMRect;
10
+ visible: boolean;
11
+ attributeName?: string | null;
12
+ oldValue?: string | null;
13
+ newValue?: string | null;
14
+ ignoreReason?: VCIgnoreReason;
15
+ }>;
16
+ };
17
+ export interface VCRevisionDebugDetails {
4
18
  revision: string;
5
19
  isClean: boolean;
6
- abortReason: string | null;
7
- vcLogs: Array<{
8
- time: number;
9
- viewportPercentage: number;
10
- entries: Array<{
11
- elementName: string;
12
- type: VCObserverEntryType;
13
- rect: DOMRect;
14
- visible: boolean;
15
- attributeName?: string | null;
16
- oldValue?: string | null;
17
- newValue?: string | null;
18
- }>;
19
- }>;
20
+ abortReason?: VCAbortReason | null;
21
+ vcLogs: VCLogEntry[];
20
22
  interactionId?: string;
21
23
  }
22
24
  export declare function getVCRevisionDebugDetails({ revision, isClean, abortReason, VCEntries, componentsLog, interactionId, }: {
23
25
  revision: string;
24
26
  isClean: boolean;
25
- abortReason: string | null;
27
+ abortReason?: VCAbortReason | null;
26
28
  VCEntries: VCEntryType[];
27
29
  componentsLog: ComponentsLogType;
28
30
  interactionId?: string;
29
31
  }): VCRevisionDebugDetails;
30
- export {};
@@ -1,7 +1,14 @@
1
1
  import { type UnbindFn } from 'bind-event-listener';
2
2
  import type { ComponentsLogType, VCAbortReasonType, VCEntryType, VCIgnoreReason, VCRatioType, VCRawDataType, VCResult } from '../../common/vc/types';
3
3
  import type { GetVCResultType, VCObserverInterface, VCObserverOptions } from '../types';
4
+ import { VCRevisionDebugDetails } from './getVCRevisionDebugDetails';
4
5
  import { Observers } from './observers';
6
+ declare global {
7
+ interface Window {
8
+ __ufo_devtool_onVCRevisionReady__?: (debugInfo: VCRevisionDebugDetails) => void;
9
+ __on_ufo_vc_debug_data_ready?: (debugInfo: VCRevisionDebugDetails) => void;
10
+ }
11
+ }
5
12
  export declare class VCObserver implements VCObserverInterface {
6
13
  abortReason: VCAbortReasonType;
7
14
  outOfBoundaryInfo: string;
@@ -0,0 +1,49 @@
1
+ export declare class RLLPlaceholderHandlers {
2
+ private placeholders;
3
+ private constructor();
4
+ /**
5
+ * Gets the global singleton instance of RLLPlaceholderHandlers.
6
+ * Creates the instance if it doesn't exist and stores it in globalThis.
7
+ * @returns The singleton instance of RLLPlaceholderHandlers
8
+ */
9
+ static getInstance(): RLLPlaceholderHandlers;
10
+ reset(): void;
11
+ /**
12
+ * Collects all React Loosely Lazy (RLL) placeholders from the DOM and caches their viewport intersecting rectangles.
13
+ * RLL placeholders are marked with data-lazy-begin and data-lazy-end attributes on hidden input elements.
14
+ * Performance optimized to batch getBoundingClientRect calls and minimize layout thrashing.
15
+ * Only stores the intersecting portions of rectangles that are currently visible in the viewport.
16
+ */
17
+ collectRLLPlaceholders(): void;
18
+ /**
19
+ * Traverses DOM siblings to find all elements between RLL begin and end markers.
20
+ * Based on the refElements pattern from react-loosely-lazy's platform/packages/async/react-loosely-lazy/src/collect/hydrate.ts
21
+ * Performance optimized to minimize iterations and early exit conditions.
22
+ *
23
+ * @param fromEl - The input element with data-lazy-begin attribute
24
+ * @param id - The placeholder ID to match against data-lazy-end
25
+ * @returns Array of DOM elements between the begin/end markers
26
+ */
27
+ private refElements;
28
+ /**
29
+ * Returns the cached intersecting viewport rectangles for all RLL placeholder elements.
30
+ * @returns Array of DOMRect objects representing the intersecting portions of placeholders within the viewport
31
+ */
32
+ getPlaceholders(): DOMRect[];
33
+ /**
34
+ * Checks if the given intersecting rectangle matches any of the cached RLL placeholder intersecting rectangles.
35
+ * This is designed to be called from IntersectionObserver with the intersectionRect.
36
+ * Performance optimized with early exits and minimal calculations.
37
+ * @param intersectingRect - The intersecting rectangle from IntersectionObserver
38
+ * @returns true if the intersecting rectangle matches a cached placeholder rectangle and hasn't exceeded match limit, false otherwise
39
+ */
40
+ isRLLPlaceholderHydration(intersectingRect: DOMRect): boolean;
41
+ /**
42
+ * Compares two DOMRect objects for equality with ±1 pixel tolerance.
43
+ * Performance optimized to minimize calculations and early exit on major differences.
44
+ * @param rect1 - First rectangle to compare
45
+ * @param rect2 - Second rectangle to compare
46
+ * @returns true if rectangles are within 1 pixel tolerance for all properties
47
+ */
48
+ private areRectsEqual;
49
+ }
@@ -1,6 +1,13 @@
1
1
  import type { RevisionPayloadEntry, VCAbortReason } from '../../../common/vc/types';
2
+ import { VCRevisionDebugDetails } from '../../vc-observer/getVCRevisionDebugDetails';
2
3
  import type { VCObserverEntry } from '../types';
3
4
  import type { VCCalculator, VCCalculatorParam } from './types';
5
+ declare global {
6
+ interface Window {
7
+ __ufo_devtool_onVCRevisionReady__?: (debugInfo: VCRevisionDebugDetails) => void;
8
+ __on_ufo_vc_debug_data_ready?: (debugInfo: VCRevisionDebugDetails) => void;
9
+ }
10
+ }
4
11
  export default abstract class AbstractVCCalculatorBase implements VCCalculator {
5
12
  private revisionNo;
6
13
  constructor(revisionNo: string);
@@ -1,5 +1,5 @@
1
1
  import type { ObservedWindowEvent } from './window-event-observer';
2
- export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute' | 'mutation:media' | 'layout-shift' | 'window:event' | 'unknown';
2
+ export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'layout-shift' | 'window:event' | 'unknown';
3
3
  export type ViewportEntryData = {
4
4
  readonly type: VCObserverEntryType;
5
5
  readonly elementName: string;
@@ -35,7 +35,7 @@ export type VCEntryType = {
35
35
  vc: number;
36
36
  elements: string[];
37
37
  };
38
- export type VCIgnoreReason = 'image' | 'ssr-hydration' | 'not-visible' | 'non-visual-style' | '';
38
+ export type VCIgnoreReason = 'image' | 'ssr-hydration' | 'not-visible' | 'non-visual-style' | 'rll-placeholder' | '';
39
39
  export type ComponentsLogEntry = {
40
40
  type?: string;
41
41
  targetName: string;
@@ -2,6 +2,7 @@ export type FeatureFlagValue = boolean | string | number | Record<any, any>;
2
2
  export type ReportedTiming = {
3
3
  startTime: number;
4
4
  duration: number;
5
+ size?: number;
5
6
  };
6
7
  export type ReportedTimings = {
7
8
  [key: string]: ReportedTiming;
@@ -1,5 +1,6 @@
1
1
  import type { VCRawDataType, VCResult } from '../common/vc/types';
2
2
  import type { GetVCResultType, VCObserverInterface, VCObserverOptions } from './types';
3
+ export type { VCRevisionDebugDetails } from './vc-observer/getVCRevisionDebugDetails';
3
4
  declare global {
4
5
  var __vcObserver: VCObserverInterface;
5
6
  }
@@ -1,30 +1,31 @@
1
- import type { ComponentsLogType, VCEntryType } from '../../common/vc/types';
1
+ import type { ComponentsLogType, VCAbortReason, VCEntryType, VCIgnoreReason } from '../../common/vc/types';
2
2
  import type { VCObserverEntryType } from '../vc-observer-new/types';
3
- interface VCRevisionDebugDetails {
3
+ export type VCLogEntry = {
4
+ time: number;
5
+ viewportPercentage: number | null;
6
+ entries: Array<{
7
+ elementName: string;
8
+ type: VCObserverEntryType;
9
+ rect: DOMRect;
10
+ visible: boolean;
11
+ attributeName?: string | null;
12
+ oldValue?: string | null;
13
+ newValue?: string | null;
14
+ ignoreReason?: VCIgnoreReason;
15
+ }>;
16
+ };
17
+ export interface VCRevisionDebugDetails {
4
18
  revision: string;
5
19
  isClean: boolean;
6
- abortReason: string | null;
7
- vcLogs: Array<{
8
- time: number;
9
- viewportPercentage: number;
10
- entries: Array<{
11
- elementName: string;
12
- type: VCObserverEntryType;
13
- rect: DOMRect;
14
- visible: boolean;
15
- attributeName?: string | null;
16
- oldValue?: string | null;
17
- newValue?: string | null;
18
- }>;
19
- }>;
20
+ abortReason?: VCAbortReason | null;
21
+ vcLogs: VCLogEntry[];
20
22
  interactionId?: string;
21
23
  }
22
24
  export declare function getVCRevisionDebugDetails({ revision, isClean, abortReason, VCEntries, componentsLog, interactionId, }: {
23
25
  revision: string;
24
26
  isClean: boolean;
25
- abortReason: string | null;
27
+ abortReason?: VCAbortReason | null;
26
28
  VCEntries: VCEntryType[];
27
29
  componentsLog: ComponentsLogType;
28
30
  interactionId?: string;
29
31
  }): VCRevisionDebugDetails;
30
- export {};
@@ -1,7 +1,14 @@
1
1
  import { type UnbindFn } from 'bind-event-listener';
2
2
  import type { ComponentsLogType, VCAbortReasonType, VCEntryType, VCIgnoreReason, VCRatioType, VCRawDataType, VCResult } from '../../common/vc/types';
3
3
  import type { GetVCResultType, VCObserverInterface, VCObserverOptions } from '../types';
4
+ import { VCRevisionDebugDetails } from './getVCRevisionDebugDetails';
4
5
  import { Observers } from './observers';
6
+ declare global {
7
+ interface Window {
8
+ __ufo_devtool_onVCRevisionReady__?: (debugInfo: VCRevisionDebugDetails) => void;
9
+ __on_ufo_vc_debug_data_ready?: (debugInfo: VCRevisionDebugDetails) => void;
10
+ }
11
+ }
5
12
  export declare class VCObserver implements VCObserverInterface {
6
13
  abortReason: VCAbortReasonType;
7
14
  outOfBoundaryInfo: string;
@@ -0,0 +1,49 @@
1
+ export declare class RLLPlaceholderHandlers {
2
+ private placeholders;
3
+ private constructor();
4
+ /**
5
+ * Gets the global singleton instance of RLLPlaceholderHandlers.
6
+ * Creates the instance if it doesn't exist and stores it in globalThis.
7
+ * @returns The singleton instance of RLLPlaceholderHandlers
8
+ */
9
+ static getInstance(): RLLPlaceholderHandlers;
10
+ reset(): void;
11
+ /**
12
+ * Collects all React Loosely Lazy (RLL) placeholders from the DOM and caches their viewport intersecting rectangles.
13
+ * RLL placeholders are marked with data-lazy-begin and data-lazy-end attributes on hidden input elements.
14
+ * Performance optimized to batch getBoundingClientRect calls and minimize layout thrashing.
15
+ * Only stores the intersecting portions of rectangles that are currently visible in the viewport.
16
+ */
17
+ collectRLLPlaceholders(): void;
18
+ /**
19
+ * Traverses DOM siblings to find all elements between RLL begin and end markers.
20
+ * Based on the refElements pattern from react-loosely-lazy's platform/packages/async/react-loosely-lazy/src/collect/hydrate.ts
21
+ * Performance optimized to minimize iterations and early exit conditions.
22
+ *
23
+ * @param fromEl - The input element with data-lazy-begin attribute
24
+ * @param id - The placeholder ID to match against data-lazy-end
25
+ * @returns Array of DOM elements between the begin/end markers
26
+ */
27
+ private refElements;
28
+ /**
29
+ * Returns the cached intersecting viewport rectangles for all RLL placeholder elements.
30
+ * @returns Array of DOMRect objects representing the intersecting portions of placeholders within the viewport
31
+ */
32
+ getPlaceholders(): DOMRect[];
33
+ /**
34
+ * Checks if the given intersecting rectangle matches any of the cached RLL placeholder intersecting rectangles.
35
+ * This is designed to be called from IntersectionObserver with the intersectionRect.
36
+ * Performance optimized with early exits and minimal calculations.
37
+ * @param intersectingRect - The intersecting rectangle from IntersectionObserver
38
+ * @returns true if the intersecting rectangle matches a cached placeholder rectangle and hasn't exceeded match limit, false otherwise
39
+ */
40
+ isRLLPlaceholderHydration(intersectingRect: DOMRect): boolean;
41
+ /**
42
+ * Compares two DOMRect objects for equality with ±1 pixel tolerance.
43
+ * Performance optimized to minimize calculations and early exit on major differences.
44
+ * @param rect1 - First rectangle to compare
45
+ * @param rect2 - Second rectangle to compare
46
+ * @returns true if rectangles are within 1 pixel tolerance for all properties
47
+ */
48
+ private areRectsEqual;
49
+ }
@@ -1,6 +1,13 @@
1
1
  import type { RevisionPayloadEntry, VCAbortReason } from '../../../common/vc/types';
2
+ import { VCRevisionDebugDetails } from '../../vc-observer/getVCRevisionDebugDetails';
2
3
  import type { VCObserverEntry } from '../types';
3
4
  import type { VCCalculator, VCCalculatorParam } from './types';
5
+ declare global {
6
+ interface Window {
7
+ __ufo_devtool_onVCRevisionReady__?: (debugInfo: VCRevisionDebugDetails) => void;
8
+ __on_ufo_vc_debug_data_ready?: (debugInfo: VCRevisionDebugDetails) => void;
9
+ }
10
+ }
4
11
  export default abstract class AbstractVCCalculatorBase implements VCCalculator {
5
12
  private revisionNo;
6
13
  constructor(revisionNo: string);
@@ -1,5 +1,5 @@
1
1
  import type { ObservedWindowEvent } from './window-event-observer';
2
- export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute' | 'mutation:media' | 'layout-shift' | 'window:event' | 'unknown';
2
+ export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'layout-shift' | 'window:event' | 'unknown';
3
3
  export type ViewportEntryData = {
4
4
  readonly type: VCObserverEntryType;
5
5
  readonly elementName: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "3.13.17",
3
+ "version": "3.13.19",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -133,6 +133,9 @@
133
133
  "platform_ufo_report_cpu_usage": {
134
134
  "type": "boolean"
135
135
  },
136
+ "platform_ufo_emit_vc_debug_data": {
137
+ "type": "boolean"
138
+ },
136
139
  "ufo_return_relative_request_start": {
137
140
  "type": "boolean"
138
141
  },
@@ -159,6 +162,12 @@
159
162
  },
160
163
  "platform_ufo_rev_ratios": {
161
164
  "type": "boolean"
165
+ },
166
+ "platform_ufo_ssr_size_field": {
167
+ "type": "boolean"
168
+ },
169
+ "platform_ufo_rll_placeholder_ignore": {
170
+ "type": "boolean"
162
171
  }
163
172
  }
164
173
  }