@atlaskit/react-ufo 5.2.9 → 5.3.0

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 (61) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/create-payload/index.js +6 -5
  3. package/dist/cjs/hidden-timing/index.js +52 -0
  4. package/dist/cjs/interaction-metrics/index.js +1 -0
  5. package/dist/cjs/interaction-metrics-init/index.js +2 -1
  6. package/dist/cjs/vc/index.js +4 -2
  7. package/dist/cjs/vc/vc-observer-new/index.js +10 -4
  8. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
  9. package/dist/cjs/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +164 -0
  10. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +173 -34
  11. package/dist/cjs/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  12. package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  13. package/dist/es2019/create-payload/index.js +5 -3
  14. package/dist/es2019/hidden-timing/index.js +51 -0
  15. package/dist/es2019/interaction-metrics/index.js +1 -0
  16. package/dist/es2019/interaction-metrics-init/index.js +2 -1
  17. package/dist/es2019/vc/index.js +4 -2
  18. package/dist/es2019/vc/vc-observer-new/index.js +10 -5
  19. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +61 -7
  20. package/dist/es2019/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +138 -0
  21. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +145 -10
  22. package/dist/es2019/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  23. package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  24. package/dist/esm/create-payload/index.js +7 -6
  25. package/dist/esm/hidden-timing/index.js +51 -0
  26. package/dist/esm/interaction-metrics/index.js +1 -0
  27. package/dist/esm/interaction-metrics-init/index.js +2 -1
  28. package/dist/esm/vc/index.js +4 -2
  29. package/dist/esm/vc/vc-observer-new/index.js +10 -4
  30. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
  31. package/dist/esm/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +158 -0
  32. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +173 -34
  33. package/dist/esm/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  34. package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  35. package/dist/types/common/react-ufo-payload-schema.d.ts +2 -0
  36. package/dist/types/common/vc/types.d.ts +55 -0
  37. package/dist/types/config/index.d.ts +1 -0
  38. package/dist/types/hidden-timing/index.d.ts +9 -0
  39. package/dist/types/vc/types.d.ts +2 -0
  40. package/dist/types/vc/vc-observer-new/index.d.ts +2 -0
  41. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  42. package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
  43. package/dist/types/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
  44. package/dist/types/vc/vc-observer-new/types.d.ts +2 -0
  45. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
  46. package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
  47. package/dist/types/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
  48. package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +2 -0
  49. package/dist/types-ts4.5/common/vc/types.d.ts +55 -0
  50. package/dist/types-ts4.5/config/index.d.ts +1 -0
  51. package/dist/types-ts4.5/hidden-timing/index.d.ts +9 -0
  52. package/dist/types-ts4.5/vc/types.d.ts +2 -0
  53. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +2 -0
  54. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  55. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
  56. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
  57. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +2 -0
  58. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
  59. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
  60. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
  61. package/package.json +4 -1
@@ -0,0 +1,31 @@
1
+ import type { LayoutShiftOffender, LayoutShiftVariables } from '../../../../common/vc/types';
2
+ import type { VCObserverEntry, ViewportEntryData } from '../../types';
3
+ type DetectLayoutShiftCauseParams = {
4
+ /**
5
+ * All viewport observer entries, used to find potential offenders close to the layout-shift timestamp.
6
+ */
7
+ viewportEntries: ReadonlyArray<VCObserverEntry & {
8
+ data: ViewportEntryData;
9
+ }>;
10
+ /**
11
+ * The layout-shift entries that contributed to a VC checkpoint.
12
+ */
13
+ layoutShiftEntries: ReadonlyArray<ViewportEntryData>;
14
+ /**
15
+ * Timestamp of the VC checkpoint entry.
16
+ */
17
+ time: number;
18
+ /**
19
+ * Start time of the interaction; used to classify whether an offender happened before the VC checkpoint.
20
+ */
21
+ startTime: number;
22
+ /**
23
+ * Window around the checkpoint timestamp used to consider "nearby" offenders.
24
+ */
25
+ offenderWindowMs?: number;
26
+ };
27
+ export declare const detectLayoutShiftCause: ({ viewportEntries, layoutShiftEntries, time, startTime, offenderWindowMs, }: DetectLayoutShiftCauseParams) => {
28
+ layoutShiftVariables: LayoutShiftVariables;
29
+ layoutShiftOffenders: LayoutShiftOffender[];
30
+ };
31
+ export {};
@@ -11,6 +11,7 @@ export type ViewportEntryData = {
11
11
  readonly oldValue?: string | null | undefined;
12
12
  readonly newValue?: string | null | undefined;
13
13
  readonly labelStacks?: VCObserverLabelStacks;
14
+ readonly originalMutationTimestamp?: DOMHighResTimeStamp;
14
15
  };
15
16
  export type VCObserverLabelStacks = {
16
17
  segment: string;
@@ -39,4 +40,5 @@ export type VCObserverGetVCResultParam = {
39
40
  includeRawData?: boolean;
40
41
  includeSSRInV3?: boolean;
41
42
  rawDataStopTime?: number;
43
+ reportLayoutShiftOffenders?: boolean;
42
44
  };
@@ -13,6 +13,7 @@ export type ViewPortObserverConstructorArgs = {
13
13
  }): void;
14
14
  getSSRState?: () => any;
15
15
  getSSRPlaceholderHandler?: () => any;
16
+ trackLayoutShiftOffenders?: boolean;
16
17
  searchPageConfig?: SearchPageConfig;
17
18
  };
18
19
  export default class ViewportObserver {
@@ -23,10 +24,11 @@ export default class ViewportObserver {
23
24
  private mapIs3pResult;
24
25
  private onChange;
25
26
  private isStarted;
27
+ private trackLayoutShiftOffenders;
26
28
  private searchPageConfig;
27
29
  private getSSRState?;
28
30
  private getSSRPlaceholderHandler?;
29
- constructor({ onChange, getSSRState, getSSRPlaceholderHandler, searchPageConfig, }: ViewPortObserverConstructorArgs);
31
+ constructor({ onChange, getSSRState, getSSRPlaceholderHandler, trackLayoutShiftOffenders, searchPageConfig, }: ViewPortObserverConstructorArgs);
30
32
  private handleIntersectionEntry;
31
33
  private handleChildListMutation;
32
34
  private handleAttributeMutation;
@@ -4,6 +4,7 @@ export type CreateMutationObserverProps = {
4
4
  attributeName: string;
5
5
  oldValue?: string | undefined | null;
6
6
  newValue?: string | undefined | null;
7
+ timestamp: DOMHighResTimeStamp;
7
8
  }) => void;
8
9
  onMutationFinished?: (props: {
9
10
  targets: Array<HTMLElement>;
@@ -1,7 +1,10 @@
1
1
  export type MutationRecordWithTimestamp = MutationRecord & {
2
2
  timestamp?: number;
3
3
  };
4
- export type AttributeMutationData = {
4
+ export type MutationDataWithTimestamp = {
5
+ timestamp?: DOMHighResTimeStamp;
6
+ };
7
+ export type AttributeMutationData = MutationDataWithTimestamp & {
5
8
  attributeName: string;
6
9
  oldValue?: string | undefined | null;
7
10
  newValue?: string | undefined | null;
@@ -9,4 +12,4 @@ export type AttributeMutationData = {
9
12
  /**
10
13
  * Add here when there are more type of mutation data
11
14
  */
12
- export type MutationData = AttributeMutationData;
15
+ export type MutationData = AttributeMutationData | MutationDataWithTimestamp;
@@ -1,4 +1,5 @@
1
1
  import { type createPayloads } from '../create-payload';
2
+ import type { HiddenTimingItem } from '../hidden-timing';
2
3
  import { type LabelStack } from '../interaction-context';
3
4
  import { type VCObserver } from '../vc/vc-observer';
4
5
  import type { AbortReasonType, ApdexType, HoldActive, InteractionError, InteractionType, MinorInteraction, SegmentInfo } from './common/types';
@@ -122,6 +123,7 @@ export type ReactUFOPayload = {
122
123
  'ufo:wasPageHiddenBeforeInit'?: boolean;
123
124
  'ufo:isOpenedInBackground'?: boolean;
124
125
  'ufo:isTabThrottled'?: boolean;
126
+ 'ufo:pageVisibilityTimeline'?: HiddenTimingItem[];
125
127
  interactionMetrics: {
126
128
  namePrefix: string;
127
129
  segmentPrefix: string;
@@ -118,6 +118,7 @@ export type CalculateTTVCResult = {
118
118
  vcDetails: RevisionPayloadVCDetails;
119
119
  ssrRatio: number;
120
120
  speedIndex: number;
121
+ VC90layoutShiftInsights: LayoutShiftInsights;
121
122
  };
122
123
  export type RawObservation = {
123
124
  t: number;
@@ -135,8 +136,31 @@ export type RawEventObservation = {
135
136
  t: number;
136
137
  evt: number;
137
138
  };
139
+ export type LayoutShiftInsightsPayload = {
140
+ impact: number;
141
+ sources: number;
142
+ same: {
143
+ dir: boolean;
144
+ dist: boolean;
145
+ };
146
+ total_mut: number;
147
+ mut: Array<{
148
+ e: string;
149
+ size: number;
150
+ attr: {
151
+ t_before: boolean;
152
+ p_above: 'all' | 'some' | 'none';
153
+ p_left: 'all' | 'some' | 'none';
154
+ p_right: 'all' | 'some' | 'none';
155
+ p_h_overlap: 'all' | 'some' | 'none';
156
+ p_v_overlap: 'all' | 'some' | 'none';
157
+ p_same_offset: 'all' | 'some' | 'none';
158
+ };
159
+ }>;
160
+ };
138
161
  export type RevisionPayloadEntry = {
139
162
  'metric:vc90': number | null;
163
+ 'vc90:ls'?: LayoutShiftInsightsPayload;
140
164
  revision: string;
141
165
  clean: boolean;
142
166
  vcDetails?: RevisionPayloadVCDetails;
@@ -162,4 +186,35 @@ export type RevisionPayloadEntry = {
162
186
  rawVCTime?: number;
163
187
  };
164
188
  export type RevisionPayload = RevisionPayloadEntry[];
189
+ export type LayoutShiftVariables = {
190
+ allHaveRects: false;
191
+ allMovedSameWay: false;
192
+ allMovedSameAmount: false;
193
+ } | {
194
+ allHaveRects: true;
195
+ allMovedSameWay: boolean;
196
+ allMovedSameAmount: boolean;
197
+ deltaX: number;
198
+ deltaY: number;
199
+ };
200
+ export type LayoutShiftOffenderMatchState = 'all' | 'some' | 'none';
201
+ export type LayoutShiftOffender = {
202
+ offender: string;
203
+ happenedBefore: boolean;
204
+ distanceToLS: number;
205
+ isAbove: LayoutShiftOffenderMatchState;
206
+ isLeft: LayoutShiftOffenderMatchState;
207
+ isRight: LayoutShiftOffenderMatchState;
208
+ hasHorizontalOverlap: LayoutShiftOffenderMatchState;
209
+ hasVerticalOverlap: LayoutShiftOffenderMatchState;
210
+ matchesLayoutShiftDelta: boolean;
211
+ };
212
+ export type LayoutShiftInsights = {
213
+ layoutShiftOffendersResult: {
214
+ layoutShiftVariables: LayoutShiftVariables;
215
+ layoutShiftOffenders: LayoutShiftOffender[];
216
+ };
217
+ layoutShiftEntriesCount: number;
218
+ layoutShiftImpact: number;
219
+ } | null;
165
220
  export {};
@@ -135,6 +135,7 @@ export type Config = {
135
135
  all: readonly TTVCRevision[];
136
136
  byExperience?: Record<string, readonly TTVCRevision[]>;
137
137
  };
138
+ readonly trackLayoutShiftOffenders?: boolean;
138
139
  };
139
140
  readonly postInteractionLog?: {
140
141
  readonly enabled?: boolean;
@@ -51,3 +51,12 @@ export declare function getThrottleMeasurements(startTime: number, endTime: numb
51
51
  * @param measurement - The throttle measurement to inject
52
52
  */
53
53
  export declare function __injectThrottleMeasurementForTesting(measurement: ThrottleMeasurement): void;
54
+ /**
55
+ * Returns the page visibility timeline entries within the specified time window.
56
+ * Each entry contains the time (relative to startTime) and whether the page was hidden.
57
+ *
58
+ * @param startTime - The start timestamp of the window (DOMHighResTimeStamp)
59
+ * @param endTime - The end timestamp of the window (DOMHighResTimeStamp)
60
+ * @returns Array of HiddenTimingItem entries within the time window, with times relative to startTime
61
+ */
62
+ export declare function getPageVisibilityTimeline(startTime: number, endTime: number): HiddenTimingItem[];
@@ -19,6 +19,7 @@ export type GetVCResultType = {
19
19
  interactionAbortReason?: AbortReasonType;
20
20
  includeRawData?: boolean;
21
21
  rawDataStopTime?: number;
22
+ reportLayoutShiftOffenders?: boolean;
22
23
  };
23
24
  export type SelectorConfig = {
24
25
  id: boolean;
@@ -48,6 +49,7 @@ export type VCObserverOptions = {
48
49
  isPostInteraction?: boolean;
49
50
  ssrEnablePageLayoutPlaceholder?: boolean;
50
51
  ssrPlaceholderHandler?: any;
52
+ trackLayoutShiftOffenders?: boolean;
51
53
  searchPageConfig?: SearchPageConfig;
52
54
  };
53
55
  export interface VCObserverInterface {
@@ -10,6 +10,7 @@ export type VCObserverNewConfig = {
10
10
  enablePageLayoutPlaceholder?: boolean;
11
11
  };
12
12
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
13
+ trackLayoutShiftOffenders?: boolean;
13
14
  searchPageConfig?: SearchPageConfig;
14
15
  };
15
16
  declare const SSRState: {
@@ -31,6 +32,7 @@ export default class VCObserverNew {
31
32
  private windowEventObserver;
32
33
  private entriesTimeline;
33
34
  private isPostInteraction;
35
+ private trackLayoutShiftOffenders;
34
36
  private ssrPlaceholderHandler;
35
37
  private ssr;
36
38
  constructor(config: VCObserverNewConfig);
@@ -25,5 +25,5 @@ export default abstract class AbstractVCCalculatorBase implements VCCalculator {
25
25
  private calculateRatios;
26
26
  private getLabelStacks;
27
27
  private calculateWithDebugInfo;
28
- calculate({ startTime, stopTime, orderedEntries, interactionId, isPostInteraction, include3p, excludeSmartAnswersInSearch, includeSSRRatio, interactionType, isPageVisible, interactionAbortReason, }: VCCalculatorParam): Promise<RevisionPayloadEntry | undefined>;
28
+ calculate({ startTime, stopTime, orderedEntries, interactionId, isPostInteraction, include3p, excludeSmartAnswersInSearch, includeSSRRatio, interactionType, isPageVisible, interactionAbortReason, reportLayoutShiftOffenders, }: VCCalculatorParam): Promise<RevisionPayloadEntry | undefined>;
29
29
  }
@@ -13,6 +13,7 @@ export type VCCalculatorParam = {
13
13
  interactionType: InteractionType;
14
14
  isPageVisible: boolean;
15
15
  interactionAbortReason?: AbortReasonType;
16
+ reportLayoutShiftOffenders?: boolean;
16
17
  };
17
18
  export interface VCCalculator {
18
19
  calculate(param: VCCalculatorParam): Promise<RevisionPayloadEntry | undefined>;
@@ -0,0 +1,31 @@
1
+ import type { LayoutShiftOffender, LayoutShiftVariables } from '../../../../common/vc/types';
2
+ import type { VCObserverEntry, ViewportEntryData } from '../../types';
3
+ type DetectLayoutShiftCauseParams = {
4
+ /**
5
+ * All viewport observer entries, used to find potential offenders close to the layout-shift timestamp.
6
+ */
7
+ viewportEntries: ReadonlyArray<VCObserverEntry & {
8
+ data: ViewportEntryData;
9
+ }>;
10
+ /**
11
+ * The layout-shift entries that contributed to a VC checkpoint.
12
+ */
13
+ layoutShiftEntries: ReadonlyArray<ViewportEntryData>;
14
+ /**
15
+ * Timestamp of the VC checkpoint entry.
16
+ */
17
+ time: number;
18
+ /**
19
+ * Start time of the interaction; used to classify whether an offender happened before the VC checkpoint.
20
+ */
21
+ startTime: number;
22
+ /**
23
+ * Window around the checkpoint timestamp used to consider "nearby" offenders.
24
+ */
25
+ offenderWindowMs?: number;
26
+ };
27
+ export declare const detectLayoutShiftCause: ({ viewportEntries, layoutShiftEntries, time, startTime, offenderWindowMs, }: DetectLayoutShiftCauseParams) => {
28
+ layoutShiftVariables: LayoutShiftVariables;
29
+ layoutShiftOffenders: LayoutShiftOffender[];
30
+ };
31
+ export {};
@@ -11,6 +11,7 @@ export type ViewportEntryData = {
11
11
  readonly oldValue?: string | null | undefined;
12
12
  readonly newValue?: string | null | undefined;
13
13
  readonly labelStacks?: VCObserverLabelStacks;
14
+ readonly originalMutationTimestamp?: DOMHighResTimeStamp;
14
15
  };
15
16
  export type VCObserverLabelStacks = {
16
17
  segment: string;
@@ -39,4 +40,5 @@ export type VCObserverGetVCResultParam = {
39
40
  includeRawData?: boolean;
40
41
  includeSSRInV3?: boolean;
41
42
  rawDataStopTime?: number;
43
+ reportLayoutShiftOffenders?: boolean;
42
44
  };
@@ -13,6 +13,7 @@ export type ViewPortObserverConstructorArgs = {
13
13
  }): void;
14
14
  getSSRState?: () => any;
15
15
  getSSRPlaceholderHandler?: () => any;
16
+ trackLayoutShiftOffenders?: boolean;
16
17
  searchPageConfig?: SearchPageConfig;
17
18
  };
18
19
  export default class ViewportObserver {
@@ -23,10 +24,11 @@ export default class ViewportObserver {
23
24
  private mapIs3pResult;
24
25
  private onChange;
25
26
  private isStarted;
27
+ private trackLayoutShiftOffenders;
26
28
  private searchPageConfig;
27
29
  private getSSRState?;
28
30
  private getSSRPlaceholderHandler?;
29
- constructor({ onChange, getSSRState, getSSRPlaceholderHandler, searchPageConfig, }: ViewPortObserverConstructorArgs);
31
+ constructor({ onChange, getSSRState, getSSRPlaceholderHandler, trackLayoutShiftOffenders, searchPageConfig, }: ViewPortObserverConstructorArgs);
30
32
  private handleIntersectionEntry;
31
33
  private handleChildListMutation;
32
34
  private handleAttributeMutation;
@@ -4,6 +4,7 @@ export type CreateMutationObserverProps = {
4
4
  attributeName: string;
5
5
  oldValue?: string | undefined | null;
6
6
  newValue?: string | undefined | null;
7
+ timestamp: DOMHighResTimeStamp;
7
8
  }) => void;
8
9
  onMutationFinished?: (props: {
9
10
  targets: Array<HTMLElement>;
@@ -1,7 +1,10 @@
1
1
  export type MutationRecordWithTimestamp = MutationRecord & {
2
2
  timestamp?: number;
3
3
  };
4
- export type AttributeMutationData = {
4
+ export type MutationDataWithTimestamp = {
5
+ timestamp?: DOMHighResTimeStamp;
6
+ };
7
+ export type AttributeMutationData = MutationDataWithTimestamp & {
5
8
  attributeName: string;
6
9
  oldValue?: string | undefined | null;
7
10
  newValue?: string | undefined | null;
@@ -9,4 +12,4 @@ export type AttributeMutationData = {
9
12
  /**
10
13
  * Add here when there are more type of mutation data
11
14
  */
12
- export type MutationData = AttributeMutationData;
15
+ export type MutationData = AttributeMutationData | MutationDataWithTimestamp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "5.2.9",
3
+ "version": "5.3.0",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -208,6 +208,9 @@
208
208
  },
209
209
  "platform_ufo_enable_killswitch_config": {
210
210
  "type": "boolean"
211
+ },
212
+ "platform_ufo_page_visibility_timeline": {
213
+ "type": "boolean"
211
214
  }
212
215
  }
213
216
  }