@openreplay/tracker 3.5.16 → 3.6.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 (128) hide show
  1. package/.eslintignore +8 -0
  2. package/.prettierignore +1 -0
  3. package/LICENSE +1 -1
  4. package/cjs/app/guards.d.ts +2 -1
  5. package/cjs/app/guards.js +6 -3
  6. package/cjs/app/index.d.ts +28 -23
  7. package/cjs/app/index.js +107 -86
  8. package/cjs/app/logger.js +6 -3
  9. package/cjs/app/messages.d.ts +52 -0
  10. package/cjs/app/messages.gen.d.ts +57 -0
  11. package/cjs/app/messages.gen.js +493 -0
  12. package/cjs/app/messages.js +234 -0
  13. package/cjs/app/nodes.d.ts +1 -1
  14. package/cjs/app/nodes.js +2 -0
  15. package/cjs/app/observer/iframe_observer.d.ts +1 -1
  16. package/cjs/app/observer/iframe_observer.js +3 -3
  17. package/cjs/app/observer/observer.d.ts +2 -3
  18. package/cjs/app/observer/observer.js +50 -52
  19. package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
  20. package/cjs/app/observer/shadow_root_observer.js +3 -3
  21. package/cjs/app/observer/top_observer.d.ts +13 -2
  22. package/cjs/app/observer/top_observer.js +58 -23
  23. package/cjs/app/sanitizer.d.ts +1 -1
  24. package/cjs/app/sanitizer.js +5 -5
  25. package/cjs/app/session.d.ts +20 -2
  26. package/cjs/app/session.js +65 -6
  27. package/cjs/app/ticker.d.ts +1 -1
  28. package/cjs/common/{webworker.d.ts → interaction.d.ts} +5 -5
  29. package/cjs/common/{types.js → interaction.js} +0 -0
  30. package/cjs/common/messages.gen.d.ts +382 -0
  31. package/cjs/common/{webworker.js → messages.gen.js} +1 -0
  32. package/cjs/index.d.ts +10 -9
  33. package/cjs/index.js +47 -36
  34. package/cjs/modules/adoptedStyleSheets.d.ts +2 -0
  35. package/cjs/modules/adoptedStyleSheets.js +127 -0
  36. package/cjs/modules/connection.d.ts +1 -1
  37. package/cjs/modules/connection.js +2 -2
  38. package/cjs/modules/console.d.ts +1 -1
  39. package/cjs/modules/console.js +7 -21
  40. package/cjs/modules/cssrules.d.ts +1 -1
  41. package/cjs/modules/cssrules.js +18 -14
  42. package/cjs/modules/exception.d.ts +3 -3
  43. package/cjs/modules/exception.js +23 -18
  44. package/cjs/modules/img.d.ts +1 -1
  45. package/cjs/modules/img.js +39 -26
  46. package/cjs/modules/input.d.ts +1 -1
  47. package/cjs/modules/input.js +21 -21
  48. package/cjs/modules/mouse.d.ts +1 -1
  49. package/cjs/modules/mouse.js +50 -43
  50. package/cjs/modules/performance.d.ts +1 -1
  51. package/cjs/modules/performance.js +2 -2
  52. package/cjs/modules/scroll.d.ts +1 -1
  53. package/cjs/modules/scroll.js +16 -7
  54. package/cjs/modules/timing.d.ts +1 -1
  55. package/cjs/modules/timing.js +14 -26
  56. package/cjs/modules/viewport.d.ts +1 -1
  57. package/cjs/modules/viewport.js +4 -4
  58. package/cjs/utils.js +7 -7
  59. package/cjs/vendors/finder/finder.js +53 -48
  60. package/lib/app/guards.d.ts +2 -1
  61. package/lib/app/guards.js +4 -2
  62. package/lib/app/index.d.ts +28 -23
  63. package/lib/app/index.js +115 -94
  64. package/lib/app/logger.js +6 -3
  65. package/lib/app/messages.d.ts +52 -0
  66. package/lib/app/messages.gen.d.ts +57 -0
  67. package/lib/app/messages.gen.js +434 -0
  68. package/lib/app/messages.js +181 -0
  69. package/lib/app/nodes.d.ts +1 -1
  70. package/lib/app/nodes.js +2 -0
  71. package/lib/app/observer/iframe_observer.d.ts +1 -1
  72. package/lib/app/observer/iframe_observer.js +3 -3
  73. package/lib/app/observer/observer.d.ts +2 -3
  74. package/lib/app/observer/observer.js +51 -53
  75. package/lib/app/observer/shadow_root_observer.d.ts +1 -1
  76. package/lib/app/observer/shadow_root_observer.js +3 -3
  77. package/lib/app/observer/top_observer.d.ts +13 -2
  78. package/lib/app/observer/top_observer.js +62 -27
  79. package/lib/app/sanitizer.d.ts +1 -1
  80. package/lib/app/sanitizer.js +7 -7
  81. package/lib/app/session.d.ts +20 -2
  82. package/lib/app/session.js +65 -6
  83. package/lib/app/ticker.d.ts +1 -1
  84. package/lib/common/{webworker.d.ts → interaction.d.ts} +5 -5
  85. package/lib/common/{types.js → interaction.js} +0 -0
  86. package/lib/common/messages.gen.d.ts +382 -0
  87. package/lib/common/messages.gen.js +2 -0
  88. package/lib/common/tsconfig.tsbuildinfo +1 -1
  89. package/lib/index.d.ts +10 -9
  90. package/lib/index.js +60 -49
  91. package/lib/modules/adoptedStyleSheets.d.ts +2 -0
  92. package/lib/modules/adoptedStyleSheets.js +124 -0
  93. package/lib/modules/connection.d.ts +1 -1
  94. package/lib/modules/connection.js +2 -2
  95. package/lib/modules/console.d.ts +1 -1
  96. package/lib/modules/console.js +8 -22
  97. package/lib/modules/cssrules.d.ts +1 -1
  98. package/lib/modules/cssrules.js +19 -15
  99. package/lib/modules/exception.d.ts +3 -3
  100. package/lib/modules/exception.js +23 -18
  101. package/lib/modules/img.d.ts +1 -1
  102. package/lib/modules/img.js +41 -28
  103. package/lib/modules/input.d.ts +1 -1
  104. package/lib/modules/input.js +23 -23
  105. package/lib/modules/mouse.d.ts +1 -1
  106. package/lib/modules/mouse.js +53 -46
  107. package/lib/modules/performance.d.ts +1 -1
  108. package/lib/modules/performance.js +3 -3
  109. package/lib/modules/scroll.d.ts +1 -1
  110. package/lib/modules/scroll.js +17 -8
  111. package/lib/modules/timing.d.ts +1 -1
  112. package/lib/modules/timing.js +16 -28
  113. package/lib/modules/viewport.d.ts +1 -1
  114. package/lib/modules/viewport.js +4 -4
  115. package/lib/utils.js +7 -7
  116. package/lib/vendors/finder/finder.js +53 -48
  117. package/package.json +27 -10
  118. package/cjs/common/messages.d.ts +0 -444
  119. package/cjs/common/messages.js +0 -794
  120. package/cjs/common/types.d.ts +0 -9
  121. package/cjs/modules/longtasks.d.ts +0 -2
  122. package/cjs/modules/longtasks.js +0 -26
  123. package/lib/common/messages.d.ts +0 -444
  124. package/lib/common/messages.js +0 -790
  125. package/lib/common/types.d.ts +0 -9
  126. package/lib/common/webworker.js +0 -1
  127. package/lib/modules/longtasks.d.ts +0 -2
  128. package/lib/modules/longtasks.js +0 -23
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ // Auto-generated, do not edit
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.CreateIFrameDocument = exports.MouseClick = exports.CSSInsertRuleURLBased = exports.CustomIssue = exports.TechnicalInfo = exports.SetCSSDataURLBased = exports.SetNodeAttributeURLBased = exports.LongTask = exports.SetPageVisibility = exports.ConnectionInformation = exports.ResourceTiming = exports.PerformanceTrack = exports.GraphQL = exports.NgRx = exports.MobX = exports.Vuex = exports.Redux = exports.StateAction = exports.OTable = exports.Profiler = exports.Fetch = exports.CSSDeleteRule = exports.CSSInsertRule = exports.Metadata = exports.UserAnonymousID = exports.UserID = exports.RawCustomEvent = exports.JSException = exports.PageRenderTiming = exports.PageLoadTiming = exports.ConsoleLog = 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 = exports.PartitionedMessage = exports.BatchMetadata = void 0;
5
+ function BatchMetadata(version, pageNo, firstIndex, timestamp, location) {
6
+ return [81 /* BatchMetadata */, version, pageNo, firstIndex, timestamp, location];
7
+ }
8
+ exports.BatchMetadata = BatchMetadata;
9
+ function PartitionedMessage(partNo, partTotal) {
10
+ return [82 /* PartitionedMessage */, partNo, partTotal];
11
+ }
12
+ exports.PartitionedMessage = PartitionedMessage;
13
+ function Timestamp(timestamp) {
14
+ return [0 /* Timestamp */, timestamp];
15
+ }
16
+ exports.Timestamp = Timestamp;
17
+ function SetPageLocation(url, referrer, navigationStart) {
18
+ return [4 /* SetPageLocation */, url, referrer, navigationStart];
19
+ }
20
+ exports.SetPageLocation = SetPageLocation;
21
+ function SetViewportSize(width, height) {
22
+ return [5 /* SetViewportSize */, width, height];
23
+ }
24
+ exports.SetViewportSize = SetViewportSize;
25
+ function SetViewportScroll(x, y) {
26
+ return [6 /* SetViewportScroll */, x, y];
27
+ }
28
+ exports.SetViewportScroll = SetViewportScroll;
29
+ function CreateDocument() {
30
+ return [7 /* CreateDocument */];
31
+ }
32
+ exports.CreateDocument = CreateDocument;
33
+ function CreateElementNode(id, parentID, index, tag, svg) {
34
+ return [8 /* CreateElementNode */, id, parentID, index, tag, svg];
35
+ }
36
+ exports.CreateElementNode = CreateElementNode;
37
+ function CreateTextNode(id, parentID, index) {
38
+ return [9 /* CreateTextNode */, id, parentID, index];
39
+ }
40
+ exports.CreateTextNode = CreateTextNode;
41
+ function MoveNode(id, parentID, index) {
42
+ return [10 /* MoveNode */, id, parentID, index];
43
+ }
44
+ exports.MoveNode = MoveNode;
45
+ function RemoveNode(id) {
46
+ return [11 /* RemoveNode */, id];
47
+ }
48
+ exports.RemoveNode = RemoveNode;
49
+ function SetNodeAttribute(id, name, value) {
50
+ return [12 /* SetNodeAttribute */, id, name, value];
51
+ }
52
+ exports.SetNodeAttribute = SetNodeAttribute;
53
+ function RemoveNodeAttribute(id, name) {
54
+ return [13 /* RemoveNodeAttribute */, id, name];
55
+ }
56
+ exports.RemoveNodeAttribute = RemoveNodeAttribute;
57
+ function SetNodeData(id, data) {
58
+ return [14 /* SetNodeData */, id, data];
59
+ }
60
+ exports.SetNodeData = SetNodeData;
61
+ function SetNodeScroll(id, x, y) {
62
+ return [16 /* SetNodeScroll */, id, x, y];
63
+ }
64
+ exports.SetNodeScroll = SetNodeScroll;
65
+ function SetInputTarget(id, label) {
66
+ return [17 /* SetInputTarget */, id, label];
67
+ }
68
+ exports.SetInputTarget = SetInputTarget;
69
+ function SetInputValue(id, value, mask) {
70
+ return [18 /* SetInputValue */, id, value, mask];
71
+ }
72
+ exports.SetInputValue = SetInputValue;
73
+ function SetInputChecked(id, checked) {
74
+ return [19 /* SetInputChecked */, id, checked];
75
+ }
76
+ exports.SetInputChecked = SetInputChecked;
77
+ function MouseMove(x, y) {
78
+ return [20 /* MouseMove */, x, y];
79
+ }
80
+ exports.MouseMove = MouseMove;
81
+ function ConsoleLog(level, value) {
82
+ return [22 /* ConsoleLog */, level, value];
83
+ }
84
+ exports.ConsoleLog = ConsoleLog;
85
+ function PageLoadTiming(requestStart, responseStart, responseEnd, domContentLoadedEventStart, domContentLoadedEventEnd, loadEventStart, loadEventEnd, firstPaint, firstContentfulPaint) {
86
+ return [
87
+ 23 /* PageLoadTiming */,
88
+ requestStart,
89
+ responseStart,
90
+ responseEnd,
91
+ domContentLoadedEventStart,
92
+ domContentLoadedEventEnd,
93
+ loadEventStart,
94
+ loadEventEnd,
95
+ firstPaint,
96
+ firstContentfulPaint,
97
+ ];
98
+ }
99
+ exports.PageLoadTiming = PageLoadTiming;
100
+ function PageRenderTiming(speedIndex, visuallyComplete, timeToInteractive) {
101
+ return [24 /* PageRenderTiming */, speedIndex, visuallyComplete, timeToInteractive];
102
+ }
103
+ exports.PageRenderTiming = PageRenderTiming;
104
+ function JSException(name, message, payload) {
105
+ return [25 /* JSException */, name, message, payload];
106
+ }
107
+ exports.JSException = JSException;
108
+ function RawCustomEvent(name, payload) {
109
+ return [27 /* RawCustomEvent */, name, payload];
110
+ }
111
+ exports.RawCustomEvent = RawCustomEvent;
112
+ function UserID(id) {
113
+ return [28 /* UserID */, id];
114
+ }
115
+ exports.UserID = UserID;
116
+ function UserAnonymousID(id) {
117
+ return [29 /* UserAnonymousID */, id];
118
+ }
119
+ exports.UserAnonymousID = UserAnonymousID;
120
+ function Metadata(key, value) {
121
+ return [30 /* Metadata */, key, value];
122
+ }
123
+ exports.Metadata = Metadata;
124
+ function CSSInsertRule(id, rule, index) {
125
+ return [37 /* CSSInsertRule */, id, rule, index];
126
+ }
127
+ exports.CSSInsertRule = CSSInsertRule;
128
+ function CSSDeleteRule(id, index) {
129
+ return [38 /* CSSDeleteRule */, id, index];
130
+ }
131
+ exports.CSSDeleteRule = CSSDeleteRule;
132
+ function Fetch(method, url, request, response, status, timestamp, duration) {
133
+ return [39 /* Fetch */, method, url, request, response, status, timestamp, duration];
134
+ }
135
+ exports.Fetch = Fetch;
136
+ function Profiler(name, duration, args, result) {
137
+ return [40 /* Profiler */, name, duration, args, result];
138
+ }
139
+ exports.Profiler = Profiler;
140
+ function OTable(key, value) {
141
+ return [41 /* OTable */, key, value];
142
+ }
143
+ exports.OTable = OTable;
144
+ function StateAction(type) {
145
+ return [42 /* StateAction */, type];
146
+ }
147
+ exports.StateAction = StateAction;
148
+ function Redux(action, state, duration) {
149
+ return [44 /* Redux */, action, state, duration];
150
+ }
151
+ exports.Redux = Redux;
152
+ function Vuex(mutation, state) {
153
+ return [45 /* Vuex */, mutation, state];
154
+ }
155
+ exports.Vuex = Vuex;
156
+ function MobX(type, payload) {
157
+ return [46 /* MobX */, type, payload];
158
+ }
159
+ exports.MobX = MobX;
160
+ function NgRx(action, state, duration) {
161
+ return [47 /* NgRx */, action, state, duration];
162
+ }
163
+ exports.NgRx = NgRx;
164
+ function GraphQL(operationKind, operationName, variables, response) {
165
+ return [48 /* GraphQL */, operationKind, operationName, variables, response];
166
+ }
167
+ exports.GraphQL = GraphQL;
168
+ function PerformanceTrack(frames, ticks, totalJSHeapSize, usedJSHeapSize) {
169
+ return [49 /* PerformanceTrack */, frames, ticks, totalJSHeapSize, usedJSHeapSize];
170
+ }
171
+ exports.PerformanceTrack = PerformanceTrack;
172
+ function ResourceTiming(timestamp, duration, ttfb, headerSize, encodedBodySize, decodedBodySize, url, initiator) {
173
+ return [
174
+ 53 /* ResourceTiming */,
175
+ timestamp,
176
+ duration,
177
+ ttfb,
178
+ headerSize,
179
+ encodedBodySize,
180
+ decodedBodySize,
181
+ url,
182
+ initiator,
183
+ ];
184
+ }
185
+ exports.ResourceTiming = ResourceTiming;
186
+ function ConnectionInformation(downlink, type) {
187
+ return [54 /* ConnectionInformation */, downlink, type];
188
+ }
189
+ exports.ConnectionInformation = ConnectionInformation;
190
+ function SetPageVisibility(hidden) {
191
+ return [55 /* SetPageVisibility */, hidden];
192
+ }
193
+ exports.SetPageVisibility = SetPageVisibility;
194
+ function LongTask(timestamp, duration, context, containerType, containerSrc, containerId, containerName) {
195
+ return [
196
+ 59 /* LongTask */,
197
+ timestamp,
198
+ duration,
199
+ context,
200
+ containerType,
201
+ containerSrc,
202
+ containerId,
203
+ containerName,
204
+ ];
205
+ }
206
+ exports.LongTask = LongTask;
207
+ function SetNodeAttributeURLBased(id, name, value, baseURL) {
208
+ return [60 /* SetNodeAttributeURLBased */, id, name, value, baseURL];
209
+ }
210
+ exports.SetNodeAttributeURLBased = SetNodeAttributeURLBased;
211
+ function SetCSSDataURLBased(id, data, baseURL) {
212
+ return [61 /* SetCSSDataURLBased */, id, data, baseURL];
213
+ }
214
+ exports.SetCSSDataURLBased = SetCSSDataURLBased;
215
+ function TechnicalInfo(type, value) {
216
+ return [63 /* TechnicalInfo */, type, value];
217
+ }
218
+ exports.TechnicalInfo = TechnicalInfo;
219
+ function CustomIssue(name, payload) {
220
+ return [64 /* CustomIssue */, name, payload];
221
+ }
222
+ exports.CustomIssue = CustomIssue;
223
+ function CSSInsertRuleURLBased(id, rule, index, baseURL) {
224
+ return [67 /* CSSInsertRuleURLBased */, id, rule, index, baseURL];
225
+ }
226
+ exports.CSSInsertRuleURLBased = CSSInsertRuleURLBased;
227
+ function MouseClick(id, hesitationTime, label, selector) {
228
+ return [69 /* MouseClick */, id, hesitationTime, label, selector];
229
+ }
230
+ exports.MouseClick = MouseClick;
231
+ function CreateIFrameDocument(frameID, id) {
232
+ return [70 /* CreateIFrameDocument */, frameID, id];
233
+ }
234
+ exports.CreateIFrameDocument = CreateIFrameDocument;
@@ -7,7 +7,7 @@ export default class Nodes {
7
7
  constructor(node_id: string);
8
8
  attachNodeCallback(nodeCallback: NodeCallback): void;
9
9
  attachElementListener(type: string, node: Element, elementListener: EventListener): void;
10
- registerNode(node: Node): [id: number, isNew: boolean];
10
+ registerNode(node: Node): [/*id:*/ number, /*isNew:*/ boolean];
11
11
  unregisterNode(node: Node): number | undefined;
12
12
  cleanTree(): void;
13
13
  callNodeCallbacks(node: Node, isStart: boolean): void;
package/cjs/app/nodes.js CHANGED
@@ -7,9 +7,11 @@ class Nodes {
7
7
  this.nodeCallbacks = [];
8
8
  this.elementListeners = new Map();
9
9
  }
10
+ // Attached once per Tracker instance
10
11
  attachNodeCallback(nodeCallback) {
11
12
  this.nodeCallbacks.push(nodeCallback);
12
13
  }
14
+ // TODO: what is the difference with app.attachEventListener. can we use only one of those?
13
15
  attachElementListener(type, node, elementListener) {
14
16
  const id = this.getID(node);
15
17
  if (id === undefined) {
@@ -1,4 +1,4 @@
1
- import Observer from "./observer.js";
1
+ import Observer from './observer.js';
2
2
  export default class IFrameObserver extends Observer {
3
3
  observe(iframe: HTMLIFrameElement): void;
4
4
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const observer_js_1 = require("./observer.js");
4
- const messages_js_1 = require("../../common/messages.js");
4
+ const messages_gen_js_1 = require("../messages.gen.js");
5
5
  class IFrameObserver extends observer_js_1.default {
6
6
  observe(iframe) {
7
7
  const doc = iframe.contentDocument;
@@ -12,10 +12,10 @@ class IFrameObserver extends observer_js_1.default {
12
12
  // Have to observe document, because the inner <html> might be changed
13
13
  this.observeRoot(doc, (docID) => {
14
14
  if (docID === undefined) {
15
- console.log("OpenReplay: Iframe document not bound");
15
+ console.log('OpenReplay: Iframe document not bound');
16
16
  return;
17
17
  }
18
- this.app.send((0, messages_js_1.CreateIFrameDocument)(hostID, docID));
18
+ this.app.send((0, messages_gen_js_1.CreateIFrameDocument)(hostID, docID));
19
19
  });
20
20
  }
21
21
  }
@@ -1,4 +1,4 @@
1
- import App from "../index.js";
1
+ import App from '../index.js';
2
2
  export default abstract class Observer {
3
3
  protected readonly app: App;
4
4
  protected readonly isTopContext: boolean;
@@ -13,9 +13,8 @@ export default abstract class Observer {
13
13
  private sendNodeAttribute;
14
14
  private sendNodeData;
15
15
  private bindNode;
16
- private unbindChildNode;
17
16
  private bindTree;
18
- private unbindNode;
17
+ private unbindTree;
19
18
  private _commitNode;
20
19
  private commitNode;
21
20
  private commitNodes;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const messages_js_1 = require("../../common/messages.js");
3
+ const messages_gen_js_1 = require("../messages.gen.js");
4
4
  const guards_js_1 = require("../guards.js");
5
5
  function isIgnored(node) {
6
6
  if ((0, guards_js_1.isTextNode)(node)) {
@@ -13,13 +13,9 @@ function isIgnored(node) {
13
13
  if (tag === 'LINK') {
14
14
  const rel = node.getAttribute('rel');
15
15
  const as = node.getAttribute('as');
16
- return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === "style" || as === "font");
16
+ return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === 'style' || as === 'font');
17
17
  }
18
- return (tag === 'SCRIPT' ||
19
- tag === 'NOSCRIPT' ||
20
- tag === 'META' ||
21
- tag === 'TITLE' ||
22
- tag === 'BASE');
18
+ return (tag === 'SCRIPT' || tag === 'NOSCRIPT' || tag === 'META' || tag === 'TITLE' || tag === 'BASE');
23
19
  }
24
20
  function isObservable(node) {
25
21
  if ((0, guards_js_1.isRootNode)(node)) {
@@ -32,17 +28,11 @@ function isObservable(node) {
32
28
  - fix unbinding logic + send all removals first (ensure sequence is correct)
33
29
  - use document as a 0-node in the upper context (should be updated in player at first)
34
30
  */
35
- /*
36
- Nikita:
37
- - rn we only send unbind event for parent (all child nodes will be cut in the live replay anyways)
38
- to prevent sending 1k+ unbinds for child nodes and making replay file bigger than it should be
39
- */
40
31
  var RecentsType;
41
32
  (function (RecentsType) {
42
33
  RecentsType[RecentsType["New"] = 0] = "New";
43
34
  RecentsType[RecentsType["Removed"] = 1] = "Removed";
44
35
  RecentsType[RecentsType["Changed"] = 2] = "Changed";
45
- RecentsType[RecentsType["RemovedChild"] = 3] = "RemovedChild";
46
36
  })(RecentsType || (RecentsType = {}));
47
37
  class Observer {
48
38
  constructor(app, isTopContext = false) {
@@ -54,7 +44,8 @@ class Observer {
54
44
  this.attributesMap = new Map();
55
45
  this.textSet = new Set();
56
46
  this.observer = new MutationObserver(this.app.safe((mutations) => {
57
- for (const mutation of mutations) { // mutations order is sequential
47
+ for (const mutation of mutations) {
48
+ // mutations order is sequential
58
49
  const target = mutation.target;
59
50
  const type = mutation.type;
60
51
  if (!isObservable(target)) {
@@ -62,7 +53,10 @@ class Observer {
62
53
  }
63
54
  if (type === 'childList') {
64
55
  for (let i = 0; i < mutation.removedNodes.length; i++) {
65
- this.bindTree(mutation.removedNodes[i], true);
56
+ // Should be the same as bindTree(mutation.removedNodes[i]), but logic needs to be be untied
57
+ if (isObservable(mutation.removedNodes[i])) {
58
+ this.bindNode(mutation.removedNodes[i]);
59
+ }
66
60
  }
67
61
  for (let i = 0; i < mutation.addedNodes.length; i++) {
68
62
  this.bindTree(mutation.addedNodes[i]);
@@ -83,7 +77,7 @@ class Observer {
83
77
  }
84
78
  let attr = this.attributesMap.get(id);
85
79
  if (attr === undefined) {
86
- this.attributesMap.set(id, attr = new Set());
80
+ this.attributesMap.set(id, (attr = new Set()));
87
81
  }
88
82
  attr.add(name);
89
83
  continue;
@@ -109,16 +103,16 @@ class Observer {
109
103
  name = name.substr(6);
110
104
  }
111
105
  if (value === null) {
112
- this.app.send(new messages_js_1.RemoveNodeAttribute(id, name));
106
+ this.app.send((0, messages_gen_js_1.RemoveNodeAttribute)(id, name));
113
107
  }
114
108
  else if (name === 'href') {
115
109
  if (value.length > 1e5) {
116
110
  value = '';
117
111
  }
118
- this.app.send(new messages_js_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
112
+ this.app.send((0, messages_gen_js_1.SetNodeAttributeURLBased)(id, name, value, this.app.getBaseHref()));
119
113
  }
120
114
  else {
121
- this.app.send(new messages_js_1.SetNodeAttribute(id, name, value));
115
+ this.app.send((0, messages_gen_js_1.SetNodeAttribute)(id, name, value));
122
116
  }
123
117
  return;
124
118
  }
@@ -131,72 +125,75 @@ class Observer {
131
125
  return;
132
126
  }
133
127
  if (name === 'value' &&
134
- (0, guards_js_1.hasTag)(node, "INPUT") &&
128
+ (0, guards_js_1.hasTag)(node, 'INPUT') &&
135
129
  node.type !== 'button' &&
136
130
  node.type !== 'reset' &&
137
131
  node.type !== 'submit') {
138
132
  return;
139
133
  }
140
134
  if (value === null) {
141
- this.app.send(new messages_js_1.RemoveNodeAttribute(id, name));
135
+ this.app.send((0, messages_gen_js_1.RemoveNodeAttribute)(id, name));
142
136
  return;
143
137
  }
144
- if (name === 'style' || name === 'href' && (0, guards_js_1.hasTag)(node, "LINK")) {
145
- this.app.send(new messages_js_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
138
+ if (name === 'style' || (name === 'href' && (0, guards_js_1.hasTag)(node, 'LINK'))) {
139
+ this.app.send((0, messages_gen_js_1.SetNodeAttributeURLBased)(id, name, value, this.app.getBaseHref()));
146
140
  return;
147
141
  }
148
142
  if (name === 'href' || value.length > 1e5) {
149
143
  value = '';
150
144
  }
151
- this.app.send(new messages_js_1.SetNodeAttribute(id, name, value));
145
+ this.app.send((0, messages_gen_js_1.SetNodeAttribute)(id, name, value));
152
146
  }
153
147
  sendNodeData(id, parentElement, data) {
154
- if ((0, guards_js_1.hasTag)(parentElement, "STYLE") || (0, guards_js_1.hasTag)(parentElement, "style")) {
155
- this.app.send(new messages_js_1.SetCSSDataURLBased(id, data, this.app.getBaseHref()));
148
+ if ((0, guards_js_1.hasTag)(parentElement, 'STYLE') || (0, guards_js_1.hasTag)(parentElement, 'style')) {
149
+ this.app.send((0, messages_gen_js_1.SetCSSDataURLBased)(id, data, this.app.getBaseHref()));
156
150
  return;
157
151
  }
158
152
  data = this.app.sanitizer.sanitize(id, data);
159
- this.app.send(new messages_js_1.SetNodeData(id, data));
153
+ this.app.send((0, messages_gen_js_1.SetNodeData)(id, data));
160
154
  }
161
155
  bindNode(node) {
162
156
  const [id, isNew] = this.app.nodes.registerNode(node);
163
157
  if (isNew) {
164
158
  this.recents.set(id, RecentsType.New);
165
159
  }
166
- else if (this.recents.get(id) !== RecentsType.New) { // can we do just `else` here?
160
+ else if (this.recents.get(id) !== RecentsType.New) {
167
161
  this.recents.set(id, RecentsType.Removed);
168
162
  }
169
163
  }
170
- unbindChildNode(node) {
171
- const [id] = this.app.nodes.registerNode(node);
172
- this.recents.set(id, RecentsType.RemovedChild);
173
- }
174
- bindTree(node, isChildUnbinding = false) {
164
+ bindTree(node) {
175
165
  if (!isObservable(node)) {
176
166
  return;
177
167
  }
178
168
  this.bindNode(node);
179
169
  const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
180
- acceptNode: (node) => isIgnored(node)
181
- || (this.app.nodes.getID(node) !== undefined && !isChildUnbinding)
170
+ acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) !== undefined
182
171
  ? NodeFilter.FILTER_REJECT
183
172
  : NodeFilter.FILTER_ACCEPT,
184
173
  },
185
174
  // @ts-ignore
186
175
  false);
187
176
  while (walker.nextNode()) {
188
- if (isChildUnbinding) {
189
- this.unbindChildNode(walker.currentNode);
190
- }
191
- else {
192
- this.bindNode(walker.currentNode);
193
- }
177
+ this.bindNode(walker.currentNode);
194
178
  }
195
179
  }
196
- unbindNode(node) {
180
+ unbindTree(node) {
197
181
  const id = this.app.nodes.unregisterNode(node);
198
182
  if (id !== undefined && this.recents.get(id) === RecentsType.Removed) {
199
- this.app.send(new messages_js_1.RemoveNode(id));
183
+ // Sending RemoveNode only for parent to maintain
184
+ this.app.send((0, messages_gen_js_1.RemoveNode)(id));
185
+ // Unregistering all the children in order to clear the memory
186
+ const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
187
+ acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) === undefined
188
+ ? NodeFilter.FILTER_REJECT
189
+ : NodeFilter.FILTER_ACCEPT,
190
+ },
191
+ // @ts-ignore
192
+ false);
193
+ while (walker.nextNode()) {
194
+ this.app.nodes.unregisterNode(walker.currentNode);
195
+ }
196
+ // MBTODO: count and send RemovedNodesCount (for the page crash detection in heuristics)
200
197
  }
201
198
  }
202
199
  // A top-consumption function on the infinite lists test. (~1% of performance resources)
@@ -209,20 +206,20 @@ class Observer {
209
206
  // Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
210
207
  // TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
211
208
  // TODO: Clean the logic (though now it workd fine)
212
- if (!(0, guards_js_1.hasTag)(node, "HTML") || !this.isTopContext) {
209
+ if (!(0, guards_js_1.hasTag)(node, 'HTML') || !this.isTopContext) {
213
210
  if (parent === null) {
214
211
  // Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
215
- // That shouldn't affect the visual rendering ( should it? )
216
- this.unbindNode(node);
212
+ // That shouldn't affect the visual rendering ( should it? maybe when transition applied? )
213
+ this.unbindTree(node);
217
214
  return false;
218
215
  }
219
216
  parentID = this.app.nodes.getID(parent);
220
217
  if (parentID === undefined) {
221
- this.unbindNode(node);
218
+ this.unbindTree(node);
222
219
  return false;
223
220
  }
224
221
  if (!this.commitNode(parentID)) {
225
- this.unbindNode(node);
222
+ this.unbindTree(node);
226
223
  return false;
227
224
  }
228
225
  this.app.sanitizer.handleNode(id, parentID, node);
@@ -261,7 +258,7 @@ class Observer {
261
258
  el.style.width = width + 'px';
262
259
  el.style.height = height + 'px';
263
260
  }
264
- this.app.send(new messages_js_1.CreateElementNode(id, parentID, index, el.tagName, (0, guards_js_1.isSVGElement)(node)));
261
+ this.app.send((0, messages_gen_js_1.CreateElementNode)(id, parentID, index, el.tagName, (0, guards_js_1.isSVGElement)(node)));
265
262
  }
266
263
  for (let i = 0; i < el.attributes.length; i++) {
267
264
  const attr = el.attributes[i];
@@ -270,13 +267,13 @@ class Observer {
270
267
  }
271
268
  else if ((0, guards_js_1.isTextNode)(node)) {
272
269
  // for text node id != 0, hence parentID !== undefined and parent is Element
273
- this.app.send(new messages_js_1.CreateTextNode(id, parentID, index));
270
+ this.app.send((0, messages_gen_js_1.CreateTextNode)(id, parentID, index));
274
271
  this.sendNodeData(id, parent, node.data);
275
272
  }
276
273
  return true;
277
274
  }
278
275
  if (recentsType === RecentsType.Removed && parentID !== undefined) {
279
- this.app.send(new messages_js_1.MoveNode(id, parentID, index));
276
+ this.app.send((0, messages_gen_js_1.MoveNode)(id, parentID, index));
280
277
  }
281
278
  const attr = this.attributesMap.get(id);
282
279
  if (attr !== undefined) {
@@ -317,7 +314,8 @@ class Observer {
317
314
  });
318
315
  this.clear();
319
316
  }
320
- // ISSSUE
317
+ // ISSSUE (nodeToBinde should be the same as node. Look at the comment about 0-node at the beginning of the file.)
318
+ // TODO: use one observer instance for all iframes/shadowRoots (composition instiad of inheritance)
321
319
  observeRoot(node, beforeCommit, nodeToBind = node) {
322
320
  this.observer.observe(node, {
323
321
  childList: true,
@@ -1,4 +1,4 @@
1
- import Observer from "./observer.js";
1
+ import Observer from './observer.js';
2
2
  export default class ShadowRootObserver extends Observer {
3
3
  observe(el: Element): void;
4
4
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const observer_js_1 = require("./observer.js");
4
- const messages_js_1 = require("../../common/messages.js");
4
+ const messages_gen_js_1 = require("../messages.gen.js");
5
5
  class ShadowRootObserver extends observer_js_1.default {
6
6
  observe(el) {
7
7
  const shRoot = el.shadowRoot;
@@ -11,10 +11,10 @@ class ShadowRootObserver extends observer_js_1.default {
11
11
  } // log
12
12
  this.observeRoot(shRoot, (rootID) => {
13
13
  if (rootID === undefined) {
14
- console.log("OpenReplay: Shadow Root was not bound");
14
+ console.log('OpenReplay: Shadow Root was not bound');
15
15
  return;
16
16
  }
17
- this.app.send((0, messages_js_1.CreateIFrameDocument)(hostID, rootID));
17
+ this.app.send((0, messages_gen_js_1.CreateIFrameDocument)(hostID, rootID));
18
18
  });
19
19
  }
20
20
  }
@@ -1,11 +1,21 @@
1
- import Observer from "./observer.js";
2
- import App from "../index.js";
1
+ import Observer from './observer.js';
2
+ import App from '../index.js';
3
3
  export interface Options {
4
4
  captureIFrames: boolean;
5
5
  }
6
+ declare type Context = Window & typeof globalThis;
7
+ declare type ContextCallback = (context: Context) => void;
8
+ declare type Offset = {
9
+ top: number;
10
+ left: number;
11
+ };
6
12
  export default class TopObserver extends Observer {
7
13
  private readonly options;
8
14
  constructor(app: App, options: Partial<Options>);
15
+ private readonly contextCallbacks;
16
+ private readonly contextsSet;
17
+ attachContextCallback(cb: ContextCallback): void;
18
+ getDocumentOffset(doc: Document): Offset;
9
19
  private iframeObservers;
10
20
  private handleIframe;
11
21
  private shadowRootObservers;
@@ -13,3 +23,4 @@ export default class TopObserver extends Observer {
13
23
  observe(): void;
14
24
  disconnect(): void;
15
25
  }
26
+ export {};