@openreplay/tracker 13.0.1 → 14.0.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 (50) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bun.lockb +0 -0
  3. package/cjs/app/canvas.d.ts +2 -0
  4. package/cjs/app/canvas.js +6 -5
  5. package/cjs/app/index.d.ts +55 -16
  6. package/cjs/app/index.js +417 -236
  7. package/cjs/app/messages.gen.d.ts +6 -3
  8. package/cjs/app/messages.gen.js +44 -10
  9. package/cjs/app/nodes.d.ts +2 -0
  10. package/cjs/app/nodes.js +15 -1
  11. package/cjs/app/observer/iframe_observer.d.ts +1 -0
  12. package/cjs/app/observer/iframe_observer.js +9 -0
  13. package/cjs/app/observer/iframe_offsets.js +0 -1
  14. package/cjs/app/observer/top_observer.d.ts +1 -0
  15. package/cjs/app/observer/top_observer.js +14 -0
  16. package/cjs/common/messages.gen.d.ts +38 -10
  17. package/cjs/index.d.ts +1 -0
  18. package/cjs/index.js +17 -8
  19. package/cjs/modules/conditionsManager.js +2 -2
  20. package/cjs/modules/mouse.js +14 -1
  21. package/cjs/modules/scroll.d.ts +1 -1
  22. package/cjs/modules/scroll.js +9 -4
  23. package/cjs/modules/viewport.js +2 -2
  24. package/cjs/utils.d.ts +2 -1
  25. package/cjs/utils.js +33 -6
  26. package/lib/app/canvas.d.ts +2 -0
  27. package/lib/app/canvas.js +6 -5
  28. package/lib/app/index.d.ts +55 -16
  29. package/lib/app/index.js +399 -218
  30. package/lib/app/messages.gen.d.ts +6 -3
  31. package/lib/app/messages.gen.js +37 -6
  32. package/lib/app/nodes.d.ts +2 -0
  33. package/lib/app/nodes.js +15 -1
  34. package/lib/app/observer/iframe_observer.d.ts +1 -0
  35. package/lib/app/observer/iframe_observer.js +9 -0
  36. package/lib/app/observer/iframe_offsets.js +0 -1
  37. package/lib/app/observer/top_observer.d.ts +1 -0
  38. package/lib/app/observer/top_observer.js +14 -0
  39. package/lib/common/messages.gen.d.ts +38 -10
  40. package/lib/common/tsconfig.tsbuildinfo +1 -1
  41. package/lib/index.d.ts +1 -0
  42. package/lib/index.js +18 -9
  43. package/lib/modules/conditionsManager.js +2 -2
  44. package/lib/modules/mouse.js +14 -1
  45. package/lib/modules/scroll.d.ts +1 -1
  46. package/lib/modules/scroll.js +9 -4
  47. package/lib/modules/viewport.js +2 -2
  48. package/lib/utils.d.ts +2 -1
  49. package/lib/utils.js +31 -5
  50. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import * as Messages from '../common/messages.gen.js';
2
2
  export { default, Type } from '../common/messages.gen.js';
3
3
  export declare function Timestamp(timestamp: number): Messages.Timestamp;
4
- export declare function SetPageLocation(url: string, referrer: string, navigationStart: number): Messages.SetPageLocation;
4
+ export declare function SetPageLocationDeprecated(url: string, referrer: string, navigationStart: number): Messages.SetPageLocationDeprecated;
5
5
  export declare function SetViewportSize(width: number, height: number): Messages.SetViewportSize;
6
6
  export declare function SetViewportScroll(x: number, y: number): Messages.SetViewportScroll;
7
7
  export declare function CreateDocument(): Messages.CreateDocument;
@@ -35,7 +35,7 @@ export declare function ReduxDeprecated(action: string, state: string, duration:
35
35
  export declare function Vuex(mutation: string, state: string): Messages.Vuex;
36
36
  export declare function MobX(type: string, payload: string): Messages.MobX;
37
37
  export declare function NgRx(action: string, state: string, duration: number): Messages.NgRx;
38
- export declare function GraphQL(operationKind: string, operationName: string, variables: string, response: string): Messages.GraphQL;
38
+ export declare function GraphQLDeprecated(operationKind: string, operationName: string, variables: string, response: string, duration: number): Messages.GraphQLDeprecated;
39
39
  export declare function PerformanceTrack(frames: number, ticks: number, totalJSHeapSize: number, usedJSHeapSize: number): Messages.PerformanceTrack;
40
40
  export declare function StringDict(key: number, value: string): Messages.StringDict;
41
41
  export declare function SetNodeAttributeDict(id: number, nameKey: number, valueKey: number): Messages.SetNodeAttributeDict;
@@ -50,7 +50,8 @@ export declare function SetCSSDataURLBased(id: number, data: string, baseURL: st
50
50
  export declare function TechnicalInfo(type: string, value: string): Messages.TechnicalInfo;
51
51
  export declare function CustomIssue(name: string, payload: string): Messages.CustomIssue;
52
52
  export declare function CSSInsertRuleURLBased(id: number, rule: string, index: number, baseURL: string): Messages.CSSInsertRuleURLBased;
53
- export declare function MouseClick(id: number, hesitationTime: number, label: string, selector: string): Messages.MouseClick;
53
+ export declare function MouseClick(id: number, hesitationTime: number, label: string, selector: string, normalizedX: number, normalizedY: number): Messages.MouseClick;
54
+ export declare function MouseClickDeprecated(id: number, hesitationTime: number, label: string, selector: string): Messages.MouseClickDeprecated;
54
55
  export declare function CreateIFrameDocument(frameID: number, id: number): Messages.CreateIFrameDocument;
55
56
  export declare function AdoptedSSReplaceURLBased(sheetID: number, text: string, baseURL: string): Messages.AdoptedSSReplaceURLBased;
56
57
  export declare function AdoptedSSInsertRuleURLBased(sheetID: number, rule: string, index: number, baseURL: string): Messages.AdoptedSSInsertRuleURLBased;
@@ -73,3 +74,5 @@ export declare function TabData(tabId: string): Messages.TabData;
73
74
  export declare function CanvasNode(nodeId: string, timestamp: number): Messages.CanvasNode;
74
75
  export declare function TagTrigger(tagId: number): Messages.TagTrigger;
75
76
  export declare function Redux(action: string, state: string, duration: number, actionTime: number): Messages.Redux;
77
+ export declare function SetPageLocation(url: string, referrer: string, navigationStart: number, documentTitle: string): Messages.SetPageLocation;
78
+ export declare function GraphQL(operationKind: string, operationName: string, variables: string, response: string, duration: number): Messages.GraphQL;
@@ -2,8 +2,8 @@
2
2
  // Auto-generated, do not edit
3
3
  /* eslint-disable */
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.CSSInsertRuleURLBased = exports.CustomIssue = exports.TechnicalInfo = exports.SetCSSDataURLBased = exports.SetNodeAttributeURLBased = exports.LongTask = exports.SetNodeFocus = exports.LoadFontFace = exports.SetPageVisibility = exports.ConnectionInformation = exports.ResourceTimingDeprecated = exports.SetNodeAttributeDict = exports.StringDict = exports.PerformanceTrack = exports.GraphQL = exports.NgRx = exports.MobX = exports.Vuex = exports.ReduxDeprecated = exports.StateAction = exports.OTable = exports.Profiler = exports.Fetch = exports.CSSDeleteRule = exports.CSSInsertRule = exports.Metadata = exports.UserAnonymousID = exports.UserID = exports.CustomEvent = exports.PageRenderTiming = exports.PageLoadTiming = exports.ConsoleLog = exports.NetworkRequestDeprecated = exports.MouseMove = exports.SetInputChecked = exports.SetInputValue = exports.SetInputTarget = exports.SetNodeScroll = exports.SetNodeData = exports.RemoveNodeAttribute = exports.SetNodeAttribute = exports.RemoveNode = exports.MoveNode = exports.CreateTextNode = exports.CreateElementNode = exports.CreateDocument = exports.SetViewportScroll = exports.SetViewportSize = exports.SetPageLocation = exports.Timestamp = void 0;
6
- exports.Redux = exports.TagTrigger = exports.CanvasNode = exports.TabData = exports.TabChange = exports.ResourceTiming = exports.UnbindNodes = exports.MouseThrashing = exports.SelectionChange = exports.InputChange = exports.WSChannel = exports.NetworkRequest = exports.PartitionedMessage = exports.BatchMetadata = exports.Zustand = exports.JSException = exports.AdoptedSSRemoveOwner = exports.AdoptedSSAddOwner = exports.AdoptedSSDeleteRule = exports.AdoptedSSInsertRuleURLBased = exports.AdoptedSSReplaceURLBased = exports.CreateIFrameDocument = exports.MouseClick = void 0;
5
+ exports.CSSInsertRuleURLBased = exports.CustomIssue = exports.TechnicalInfo = exports.SetCSSDataURLBased = exports.SetNodeAttributeURLBased = exports.LongTask = exports.SetNodeFocus = exports.LoadFontFace = exports.SetPageVisibility = exports.ConnectionInformation = exports.ResourceTimingDeprecated = exports.SetNodeAttributeDict = exports.StringDict = exports.PerformanceTrack = exports.GraphQLDeprecated = exports.NgRx = exports.MobX = exports.Vuex = exports.ReduxDeprecated = exports.StateAction = exports.OTable = exports.Profiler = exports.Fetch = exports.CSSDeleteRule = exports.CSSInsertRule = exports.Metadata = exports.UserAnonymousID = exports.UserID = exports.CustomEvent = exports.PageRenderTiming = exports.PageLoadTiming = exports.ConsoleLog = exports.NetworkRequestDeprecated = exports.MouseMove = exports.SetInputChecked = exports.SetInputValue = exports.SetInputTarget = exports.SetNodeScroll = exports.SetNodeData = exports.RemoveNodeAttribute = exports.SetNodeAttribute = exports.RemoveNode = exports.MoveNode = exports.CreateTextNode = exports.CreateElementNode = exports.CreateDocument = exports.SetViewportScroll = exports.SetViewportSize = exports.SetPageLocationDeprecated = exports.Timestamp = void 0;
6
+ exports.GraphQL = exports.SetPageLocation = exports.Redux = exports.TagTrigger = exports.CanvasNode = exports.TabData = exports.TabChange = exports.ResourceTiming = exports.UnbindNodes = exports.MouseThrashing = exports.SelectionChange = exports.InputChange = exports.WSChannel = exports.NetworkRequest = exports.PartitionedMessage = exports.BatchMetadata = exports.Zustand = exports.JSException = exports.AdoptedSSRemoveOwner = exports.AdoptedSSAddOwner = exports.AdoptedSSDeleteRule = exports.AdoptedSSInsertRuleURLBased = exports.AdoptedSSReplaceURLBased = exports.CreateIFrameDocument = exports.MouseClickDeprecated = exports.MouseClick = void 0;
7
7
  function Timestamp(timestamp) {
8
8
  return [
9
9
  0 /* Messages.Type.Timestamp */,
@@ -11,15 +11,15 @@ function Timestamp(timestamp) {
11
11
  ];
12
12
  }
13
13
  exports.Timestamp = Timestamp;
14
- function SetPageLocation(url, referrer, navigationStart) {
14
+ function SetPageLocationDeprecated(url, referrer, navigationStart) {
15
15
  return [
16
- 4 /* Messages.Type.SetPageLocation */,
16
+ 4 /* Messages.Type.SetPageLocationDeprecated */,
17
17
  url,
18
18
  referrer,
19
19
  navigationStart,
20
20
  ];
21
21
  }
22
- exports.SetPageLocation = SetPageLocation;
22
+ exports.SetPageLocationDeprecated = SetPageLocationDeprecated;
23
23
  function SetViewportSize(width, height) {
24
24
  return [
25
25
  5 /* Messages.Type.SetViewportSize */,
@@ -310,16 +310,17 @@ function NgRx(action, state, duration) {
310
310
  ];
311
311
  }
312
312
  exports.NgRx = NgRx;
313
- function GraphQL(operationKind, operationName, variables, response) {
313
+ function GraphQLDeprecated(operationKind, operationName, variables, response, duration) {
314
314
  return [
315
- 48 /* Messages.Type.GraphQL */,
315
+ 48 /* Messages.Type.GraphQLDeprecated */,
316
316
  operationKind,
317
317
  operationName,
318
318
  variables,
319
319
  response,
320
+ duration,
320
321
  ];
321
322
  }
322
- exports.GraphQL = GraphQL;
323
+ exports.GraphQLDeprecated = GraphQLDeprecated;
323
324
  function PerformanceTrack(frames, ticks, totalJSHeapSize, usedJSHeapSize) {
324
325
  return [
325
326
  49 /* Messages.Type.PerformanceTrack */,
@@ -451,16 +452,28 @@ function CSSInsertRuleURLBased(id, rule, index, baseURL) {
451
452
  ];
452
453
  }
453
454
  exports.CSSInsertRuleURLBased = CSSInsertRuleURLBased;
454
- function MouseClick(id, hesitationTime, label, selector) {
455
+ function MouseClick(id, hesitationTime, label, selector, normalizedX, normalizedY) {
455
456
  return [
456
- 69 /* Messages.Type.MouseClick */,
457
+ 68 /* Messages.Type.MouseClick */,
457
458
  id,
458
459
  hesitationTime,
459
460
  label,
460
461
  selector,
462
+ normalizedX,
463
+ normalizedY,
461
464
  ];
462
465
  }
463
466
  exports.MouseClick = MouseClick;
467
+ function MouseClickDeprecated(id, hesitationTime, label, selector) {
468
+ return [
469
+ 69 /* Messages.Type.MouseClickDeprecated */,
470
+ id,
471
+ hesitationTime,
472
+ label,
473
+ selector,
474
+ ];
475
+ }
476
+ exports.MouseClickDeprecated = MouseClickDeprecated;
464
477
  function CreateIFrameDocument(frameID, id) {
465
478
  return [
466
479
  70 /* Messages.Type.CreateIFrameDocument */,
@@ -666,3 +679,24 @@ function Redux(action, state, duration, actionTime) {
666
679
  ];
667
680
  }
668
681
  exports.Redux = Redux;
682
+ function SetPageLocation(url, referrer, navigationStart, documentTitle) {
683
+ return [
684
+ 122 /* Messages.Type.SetPageLocation */,
685
+ url,
686
+ referrer,
687
+ navigationStart,
688
+ documentTitle,
689
+ ];
690
+ }
691
+ exports.SetPageLocation = SetPageLocation;
692
+ function GraphQL(operationKind, operationName, variables, response, duration) {
693
+ return [
694
+ 123 /* Messages.Type.GraphQL */,
695
+ operationKind,
696
+ operationName,
697
+ variables,
698
+ response,
699
+ duration,
700
+ ];
701
+ }
702
+ exports.GraphQL = GraphQL;
@@ -5,7 +5,9 @@ export default class Nodes {
5
5
  private totalNodeAmount;
6
6
  private readonly nodeCallbacks;
7
7
  private readonly elementListeners;
8
+ private nextNodeId;
8
9
  constructor(node_id: string);
10
+ syntheticMode(frameOrder: number): void;
9
11
  attachNodeCallback(nodeCallback: NodeCallback): void;
10
12
  scanTree: (cb: (node: Node | void) => void) => void;
11
13
  attachNodeListener(node: Node, type: string, listener: EventListener, useCapture?: boolean): void;
package/cjs/app/nodes.js CHANGED
@@ -8,10 +8,22 @@ class Nodes {
8
8
  this.totalNodeAmount = 0;
9
9
  this.nodeCallbacks = [];
10
10
  this.elementListeners = new Map();
11
+ this.nextNodeId = 0;
11
12
  this.scanTree = (cb) => {
12
13
  this.nodes.forEach((node) => cb(node));
13
14
  };
14
15
  }
16
+ syntheticMode(frameOrder) {
17
+ const maxSafeNumber = 9007199254740900;
18
+ const placeholderSize = 99999999;
19
+ const nextFrameId = placeholderSize * frameOrder;
20
+ // I highly doubt that this will ever happen,
21
+ // but it will be easier to debug if it does
22
+ if (nextFrameId > maxSafeNumber) {
23
+ throw new Error('Placeholder id overflow');
24
+ }
25
+ this.nextNodeId = nextFrameId;
26
+ }
15
27
  // Attached once per Tracker instance
16
28
  attachNodeCallback(nodeCallback) {
17
29
  this.nodeCallbacks.push(nodeCallback);
@@ -33,8 +45,9 @@ class Nodes {
33
45
  let id = node[this.node_id];
34
46
  const isNew = id === undefined;
35
47
  if (isNew) {
48
+ id = this.nextNodeId;
36
49
  this.totalNodeAmount++;
37
- id = this.nodes.length;
50
+ this.nextNodeId++;
38
51
  this.nodes[id] = node;
39
52
  node[this.node_id] = id;
40
53
  }
@@ -90,6 +103,7 @@ class Nodes {
90
103
  }
91
104
  this.unregisterNode(node);
92
105
  }
106
+ this.nextNodeId = 0;
93
107
  this.nodes.length = 0;
94
108
  }
95
109
  }
@@ -1,4 +1,5 @@
1
1
  import Observer from './observer.js';
2
2
  export default class IFrameObserver extends Observer {
3
3
  observe(iframe: HTMLIFrameElement): void;
4
+ syntheticObserve(selfId: number, doc: Document): void;
4
5
  }
@@ -22,5 +22,14 @@ class IFrameObserver extends observer_js_1.default {
22
22
  this.app.send((0, messages_gen_js_1.CreateIFrameDocument)(hostID, docID));
23
23
  });
24
24
  }
25
+ syntheticObserve(selfId, doc) {
26
+ this.observeRoot(doc, (docID) => {
27
+ if (docID === undefined) {
28
+ this.app.debug.log('OpenReplay: Iframe document not bound');
29
+ return;
30
+ }
31
+ this.app.send((0, messages_gen_js_1.CreateIFrameDocument)(selfId, docID));
32
+ });
33
+ }
25
34
  }
26
35
  exports.default = IFrameObserver;
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // Le truc - for defining an absolute offset for (nested) iframe documents. (To track mouse movments)
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  class IFrameOffsets {
5
4
  constructor() {
@@ -19,6 +19,7 @@ export default class TopObserver extends Observer {
19
19
  private shadowRootObservers;
20
20
  private handleShadowRoot;
21
21
  observe(): void;
22
+ crossdomainObserve(selfId: number, frameOder: number): void;
22
23
  disconnect(): void;
23
24
  }
24
25
  export {};
@@ -107,6 +107,20 @@ class TopObserver extends observer_js_1.default {
107
107
  this.app.nodes.callNodeCallbacks(document, true);
108
108
  }, window.document.documentElement);
109
109
  }
110
+ crossdomainObserve(selfId, frameOder) {
111
+ const observer = this;
112
+ Element.prototype.attachShadow = function () {
113
+ // eslint-disable-next-line
114
+ const shadow = attachShadowNativeFn.apply(this, arguments);
115
+ observer.handleShadowRoot(shadow);
116
+ return shadow;
117
+ };
118
+ this.app.nodes.clear();
119
+ this.app.nodes.syntheticMode(frameOder);
120
+ const iframeObserver = new iframe_observer_js_1.default(this.app);
121
+ this.iframeObservers.push(iframeObserver);
122
+ iframeObserver.syntheticObserve(selfId, window.document);
123
+ }
110
124
  disconnect() {
111
125
  this.iframeOffsets.clear();
112
126
  Element.prototype.attachShadow = attachShadowNativeFn;
@@ -1,6 +1,6 @@
1
1
  export declare const enum Type {
2
2
  Timestamp = 0,
3
- SetPageLocation = 4,
3
+ SetPageLocationDeprecated = 4,
4
4
  SetViewportSize = 5,
5
5
  SetViewportScroll = 6,
6
6
  CreateDocument = 7,
@@ -34,7 +34,7 @@ export declare const enum Type {
34
34
  Vuex = 45,
35
35
  MobX = 46,
36
36
  NgRx = 47,
37
- GraphQL = 48,
37
+ GraphQLDeprecated = 48,
38
38
  PerformanceTrack = 49,
39
39
  StringDict = 50,
40
40
  SetNodeAttributeDict = 51,
@@ -49,7 +49,8 @@ export declare const enum Type {
49
49
  TechnicalInfo = 63,
50
50
  CustomIssue = 64,
51
51
  CSSInsertRuleURLBased = 67,
52
- MouseClick = 69,
52
+ MouseClick = 68,
53
+ MouseClickDeprecated = 69,
53
54
  CreateIFrameDocument = 70,
54
55
  AdoptedSSReplaceURLBased = 71,
55
56
  AdoptedSSInsertRuleURLBased = 73,
@@ -71,14 +72,16 @@ export declare const enum Type {
71
72
  TabData = 118,
72
73
  CanvasNode = 119,
73
74
  TagTrigger = 120,
74
- Redux = 121
75
+ Redux = 121,
76
+ SetPageLocation = 122,
77
+ GraphQL = 123
75
78
  }
76
79
  export type Timestamp = [
77
80
  Type.Timestamp,
78
81
  number
79
82
  ];
80
- export type SetPageLocation = [
81
- Type.SetPageLocation,
83
+ export type SetPageLocationDeprecated = [
84
+ Type.SetPageLocationDeprecated,
82
85
  string,
83
86
  string,
84
87
  number
@@ -274,12 +277,13 @@ export type NgRx = [
274
277
  string,
275
278
  number
276
279
  ];
277
- export type GraphQL = [
278
- Type.GraphQL,
280
+ export type GraphQLDeprecated = [
281
+ Type.GraphQLDeprecated,
279
282
  string,
280
283
  string,
281
284
  string,
282
- string
285
+ string,
286
+ number
283
287
  ];
284
288
  export type PerformanceTrack = [
285
289
  Type.PerformanceTrack,
@@ -375,6 +379,15 @@ export type MouseClick = [
375
379
  number,
376
380
  number,
377
381
  string,
382
+ string,
383
+ number,
384
+ number
385
+ ];
386
+ export type MouseClickDeprecated = [
387
+ Type.MouseClickDeprecated,
388
+ number,
389
+ number,
390
+ string,
378
391
  string
379
392
  ];
380
393
  export type CreateIFrameDocument = [
@@ -516,5 +529,20 @@ export type Redux = [
516
529
  number,
517
530
  number
518
531
  ];
519
- type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode | TagTrigger | Redux;
532
+ export type SetPageLocation = [
533
+ Type.SetPageLocation,
534
+ string,
535
+ string,
536
+ number,
537
+ string
538
+ ];
539
+ export type GraphQL = [
540
+ Type.GraphQL,
541
+ string,
542
+ string,
543
+ string,
544
+ string,
545
+ number
546
+ ];
547
+ type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL;
520
548
  export default Message;
package/cjs/index.d.ts CHANGED
@@ -33,6 +33,7 @@ export default class API {
33
33
  private readonly options;
34
34
  featureFlags: FeatureFlags;
35
35
  private readonly app;
36
+ private readonly crossdomainMode;
36
37
  constructor(options: Options);
37
38
  checkDoNotTrack: () => boolean | undefined;
38
39
  signalStartIssue: (reason: string, missingApi: string[]) => void;
package/cjs/index.js CHANGED
@@ -85,6 +85,7 @@ class API {
85
85
  constructor(options) {
86
86
  this.options = options;
87
87
  this.app = null;
88
+ this.crossdomainMode = false;
88
89
  this.checkDoNotTrack = () => {
89
90
  return (this.options.respectDoNotTrack &&
90
91
  (navigator.doNotTrack == '1' ||
@@ -97,7 +98,7 @@ class API {
97
98
  const orig = this.options.ingestPoint || index_js_1.DEFAULT_INGEST_POINT;
98
99
  req.open('POST', orig + '/v1/web/not-started');
99
100
  req.send(JSON.stringify({
100
- trackerVersion: '13.0.1',
101
+ trackerVersion: '14.0.0',
101
102
  projectKey: this.options.projectKey,
102
103
  doNotTrack,
103
104
  reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
@@ -125,6 +126,7 @@ class API {
125
126
  }
126
127
  }
127
128
  };
129
+ this.crossdomainMode = Boolean((0, utils_js_1.inIframe)() && options.crossdomain?.enabled);
128
130
  if (!utils_js_1.IN_BROWSER || !processOptions(options)) {
129
131
  return;
130
132
  }
@@ -179,25 +181,32 @@ class API {
179
181
  this.signalStartIssue('missing_api', failReason);
180
182
  return;
181
183
  }
182
- const app = new index_js_1.default(options.projectKey, options.sessionToken, options, this.signalStartIssue);
184
+ const app = new index_js_1.default(options.projectKey, options.sessionToken, options, this.signalStartIssue, this.crossdomainMode);
183
185
  this.app = app;
184
- (0, viewport_js_1.default)(app);
186
+ if (!this.crossdomainMode) {
187
+ // no need to send iframe viewport data since its a node for us
188
+ (0, viewport_js_1.default)(app);
189
+ // calculated in main window
190
+ (0, connection_js_1.default)(app);
191
+ // while we can calculate it here, trying to compute it for all parts is hard
192
+ (0, performance_js_1.default)(app, options);
193
+ // no tabs in iframes yet
194
+ (0, tabs_js_1.default)(app);
195
+ }
196
+ (0, mouse_js_1.default)(app, options.mouse);
197
+ // inside iframe, we ignore viewport scroll
198
+ (0, scroll_js_1.default)(app, this.crossdomainMode);
185
199
  (0, cssrules_js_1.default)(app);
186
200
  (0, constructedStyleSheets_js_1.default)(app);
187
- (0, connection_js_1.default)(app);
188
201
  (0, console_js_1.default)(app, options);
189
202
  (0, exception_js_1.default)(app, options);
190
203
  (0, img_js_1.default)(app);
191
204
  (0, input_js_1.default)(app, options);
192
- (0, mouse_js_1.default)(app, options.mouse);
193
205
  (0, timing_js_1.default)(app, options);
194
- (0, performance_js_1.default)(app, options);
195
- (0, scroll_js_1.default)(app);
196
206
  (0, focus_js_1.default)(app);
197
207
  (0, fonts_js_1.default)(app);
198
208
  (0, network_js_1.default)(app, options.network);
199
209
  (0, selection_js_1.default)(app);
200
- (0, tabs_js_1.default)(app);
201
210
  window.__OPENREPLAY__ = this;
202
211
  if (options.flags && options.flags.onFlagsLoad) {
203
212
  this.onFlagsLoad(options.flags.onFlagsLoad);
@@ -86,10 +86,10 @@ class ConditionsManager {
86
86
  case 27 /* Type.CustomEvent */:
87
87
  this.customEvent(message);
88
88
  break;
89
- case 69 /* Type.MouseClick */:
89
+ case 68 /* Type.MouseClick */:
90
90
  this.clickEvent(message);
91
91
  break;
92
- case 4 /* Type.SetPageLocation */:
92
+ case 122 /* Type.SetPageLocation */:
93
93
  this.pageLocationEvent(message);
94
94
  break;
95
95
  case 83 /* Type.NetworkRequest */:
@@ -165,8 +165,14 @@ function default_1(app, options) {
165
165
  }
166
166
  const id = app.nodes.getID(target);
167
167
  if (id !== undefined) {
168
+ const clickX = e.pageX;
169
+ const clickY = e.pageY;
170
+ const contentWidth = document.documentElement.scrollWidth;
171
+ const contentHeight = document.documentElement.scrollHeight;
172
+ const normalizedX = roundNumber(clickX / contentWidth);
173
+ const normalizedY = roundNumber(clickY / contentHeight);
168
174
  sendMouseMove();
169
- app.send((0, messages_gen_js_1.MouseClick)(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), isClickable(target) && !disableClickmaps ? getSelector(id, target, options) : ''), true);
175
+ app.send((0, messages_gen_js_1.MouseClick)(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), isClickable(target) && !disableClickmaps ? getSelector(id, target, options) : '', normalizedX, normalizedY), true);
170
176
  }
171
177
  mouseTarget = null;
172
178
  });
@@ -180,3 +186,10 @@ function default_1(app, options) {
180
186
  app.ticker.attach(sendMouseMove, options?.trackingOffset || 7);
181
187
  }
182
188
  exports.default = default_1;
189
+ /**
190
+ * we get 0 to 1 decimal number, convert and round it, then turn to %
191
+ * 0.39643 => 396.43 => 396 => 39.6%
192
+ * */
193
+ function roundNumber(num) {
194
+ return Math.round(num * 1e3) / 1e1;
195
+ }
@@ -1,2 +1,2 @@
1
1
  import type App from '../app/index.js';
2
- export default function (app: App): void;
2
+ export default function (app: App, insideIframe: boolean | null): void;
@@ -5,17 +5,17 @@ const guards_js_1 = require("../app/guards.js");
5
5
  function getDocumentScroll(doc) {
6
6
  const win = doc.defaultView;
7
7
  return [
8
- (win && win.pageXOffset) ||
8
+ (win && win.scrollX) ||
9
9
  (doc.documentElement && doc.documentElement.scrollLeft) ||
10
10
  (doc.body && doc.body.scrollLeft) ||
11
11
  0,
12
- (win && win.pageYOffset) ||
12
+ (win && win.scrollY) ||
13
13
  (doc.documentElement && doc.documentElement.scrollTop) ||
14
14
  (doc.body && doc.body.scrollTop) ||
15
15
  0,
16
16
  ];
17
17
  }
18
- function default_1(app) {
18
+ function default_1(app, insideIframe) {
19
19
  let documentScroll = false;
20
20
  const nodeScroll = new Map();
21
21
  function setNodeScroll(target) {
@@ -29,7 +29,12 @@ function default_1(app) {
29
29
  nodeScroll.set(target, getDocumentScroll(target));
30
30
  }
31
31
  }
32
- const sendSetViewportScroll = app.safe(() => app.send((0, messages_gen_js_1.SetViewportScroll)(...getDocumentScroll(document))));
32
+ const sendSetViewportScroll = app.safe(() => {
33
+ if (insideIframe) {
34
+ return;
35
+ }
36
+ app.send((0, messages_gen_js_1.SetViewportScroll)(...getDocumentScroll(document)));
37
+ });
33
38
  const sendSetNodeScroll = app.safe((s, node) => {
34
39
  const id = app.nodes.getID(node);
35
40
  if (id !== undefined) {
@@ -10,7 +10,7 @@ function default_1(app) {
10
10
  const { URL } = document;
11
11
  if (URL !== url) {
12
12
  url = URL;
13
- app.send((0, messages_gen_js_1.SetPageLocation)(url, referrer, navigationStart));
13
+ app.send((0, messages_gen_js_1.SetPageLocation)(url, referrer, navigationStart, document.title));
14
14
  navigationStart = 0;
15
15
  referrer = url;
16
16
  }
@@ -27,7 +27,7 @@ function default_1(app) {
27
27
  ? Function.prototype
28
28
  : app.safe(() => app.send((0, messages_gen_js_1.SetPageVisibility)(document.hidden)));
29
29
  app.attachStartCallback(() => {
30
- url = '';
30
+ url = null;
31
31
  navigationStart = (0, utils_js_1.getTimeOrigin)();
32
32
  width = height = -1;
33
33
  sendSetPageLocation();
package/cjs/utils.d.ts CHANGED
@@ -16,7 +16,7 @@ export declare function hasOpenreplayAttribute(e: Element, attr: string): boolea
16
16
  **/
17
17
  export declare function canAccessIframe(iframe: HTMLIFrameElement): boolean;
18
18
  export declare function generateRandomId(len?: number): string;
19
- export declare function inIframe(): boolean;
19
+ export declare function inIframe(): boolean | null;
20
20
  /**
21
21
  * Because angular devs decided that its a good idea to override a browser apis
22
22
  * we need to use this to achieve safe behavior
@@ -26,3 +26,4 @@ export declare function createMutationObserver(cb: MutationCallback): MutationOb
26
26
  export declare function createEventListener(target: EventTarget, event: string, cb: EventListenerOrEventListenerObject, capture?: boolean): void;
27
27
  export declare function deleteEventListener(target: EventTarget, event: string, cb: EventListenerOrEventListenerObject, capture?: boolean): void;
28
28
  export declare function requestIdleCb(callback: () => void): void;
29
+ export declare function simpleMerge<T>(defaultObj: T, givenObj: Partial<T>): T;
package/cjs/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requestIdleCb = exports.deleteEventListener = exports.createEventListener = exports.createMutationObserver = exports.ngSafeBrowserMethod = exports.inIframe = exports.generateRandomId = exports.canAccessIframe = exports.hasOpenreplayAttribute = exports.getLabelAttribute = exports.deprecationWarn = exports.DOCS_HOST = exports.isURL = exports.normSpaces = exports.stars = exports.now = exports.getTimeOrigin = exports.adjustTimeOrigin = exports.MAX_STR_LEN = exports.IS_FIREFOX = exports.IN_BROWSER = void 0;
3
+ exports.simpleMerge = exports.requestIdleCb = exports.deleteEventListener = exports.createEventListener = exports.createMutationObserver = exports.ngSafeBrowserMethod = exports.inIframe = exports.generateRandomId = exports.canAccessIframe = exports.hasOpenreplayAttribute = exports.getLabelAttribute = exports.deprecationWarn = exports.DOCS_HOST = exports.isURL = exports.normSpaces = exports.stars = exports.now = exports.getTimeOrigin = exports.adjustTimeOrigin = exports.MAX_STR_LEN = exports.IS_FIREFOX = exports.IN_BROWSER = void 0;
4
4
  const DEPRECATED_ATTRS = { htmlmasked: 'hidden', masked: 'obscured' };
5
5
  exports.IN_BROWSER = !(typeof window === 'undefined');
6
6
  exports.IS_FIREFOX = exports.IN_BROWSER && navigator.userAgent.match(/firefox|fxios/i);
@@ -89,13 +89,18 @@ function generateRandomId(len) {
89
89
  // msCrypto = IE11
90
90
  // @ts-ignore
91
91
  const safeCrypto = window.crypto || window.msCrypto;
92
- safeCrypto.getRandomValues(arr);
93
- return Array.from(arr, dec2hex).join('');
92
+ if (safeCrypto) {
93
+ safeCrypto.getRandomValues(arr);
94
+ return Array.from(arr, dec2hex).join('');
95
+ }
96
+ else {
97
+ return Array.from({ length: len || 40 }, () => dec2hex(Math.floor(Math.random() * 16))).join('');
98
+ }
94
99
  }
95
100
  exports.generateRandomId = generateRandomId;
96
101
  function inIframe() {
97
102
  try {
98
- return window.self !== window.top;
103
+ return window.self && window.top && window.self !== window.top;
99
104
  }
100
105
  catch (e) {
101
106
  return true;
@@ -125,9 +130,10 @@ function createEventListener(target, event, cb, capture) {
125
130
  target[safeAddEventListener](event, cb, capture);
126
131
  }
127
132
  catch (e) {
133
+ const msg = e.message;
128
134
  console.debug(
129
135
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
130
- `Openreplay: ${e.messages}; if this error is caused by an IframeObserver, ignore it`);
136
+ `Openreplay: ${msg}; if this error is caused by an IframeObserver, ignore it`);
131
137
  }
132
138
  }
133
139
  exports.createEventListener = createEventListener;
@@ -137,9 +143,10 @@ function deleteEventListener(target, event, cb, capture) {
137
143
  target[safeRemoveEventListener](event, cb, capture);
138
144
  }
139
145
  catch (e) {
146
+ const msg = e.message;
140
147
  console.debug(
141
148
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
142
- `Openreplay: ${e.messages}; if this error is caused by an IframeObserver, ignore it`);
149
+ `Openreplay: ${msg}; if this error is caused by an IframeObserver, ignore it`);
143
150
  }
144
151
  }
145
152
  exports.deleteEventListener = deleteEventListener;
@@ -201,3 +208,23 @@ function requestIdleCb(callback) {
201
208
  // }
202
209
  }
203
210
  exports.requestIdleCb = requestIdleCb;
211
+ function simpleMerge(defaultObj, givenObj) {
212
+ const result = { ...defaultObj };
213
+ for (const key in givenObj) {
214
+ // eslint-disable-next-line no-prototype-builtins
215
+ if (givenObj.hasOwnProperty(key)) {
216
+ const userOptionValue = givenObj[key];
217
+ const defaultOptionValue = defaultObj[key];
218
+ if (typeof userOptionValue === 'object' &&
219
+ !Array.isArray(userOptionValue) &&
220
+ userOptionValue !== null) {
221
+ result[key] = simpleMerge(defaultOptionValue || {}, userOptionValue);
222
+ }
223
+ else {
224
+ result[key] = userOptionValue;
225
+ }
226
+ }
227
+ }
228
+ return result;
229
+ }
230
+ exports.simpleMerge = simpleMerge;
@@ -5,6 +5,7 @@ interface Options {
5
5
  isDebug?: boolean;
6
6
  fixedScaling?: boolean;
7
7
  useAnimationFrame?: boolean;
8
+ fileExt?: 'webp' | 'png' | 'jpeg' | 'avif';
8
9
  }
9
10
  declare class CanvasRecorder {
10
11
  private readonly app;
@@ -12,6 +13,7 @@ declare class CanvasRecorder {
12
13
  private snapshots;
13
14
  private readonly intervals;
14
15
  private readonly interval;
16
+ private readonly fileExt;
15
17
  constructor(app: App, options: Options);
16
18
  startTracking(): void;
17
19
  restartTracking: () => void;