@openreplay/tracker 3.5.16-beta.3 → 3.6.0-beta.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/cjs/app/guards.d.ts +2 -1
  4. package/cjs/app/guards.js +6 -3
  5. package/cjs/app/index.d.ts +24 -22
  6. package/cjs/app/index.js +85 -85
  7. package/cjs/app/logger.js +6 -3
  8. package/cjs/app/messages.d.ts +52 -0
  9. package/cjs/app/messages.gen.d.ts +57 -0
  10. package/cjs/app/messages.gen.js +494 -0
  11. package/cjs/app/messages.js +235 -0
  12. package/cjs/app/nodes.d.ts +1 -1
  13. package/cjs/app/nodes.js +4 -7
  14. package/cjs/app/observer/iframe_observer.d.ts +1 -1
  15. package/cjs/app/observer/iframe_observer.js +3 -3
  16. package/cjs/app/observer/observer.d.ts +2 -2
  17. package/cjs/app/observer/observer.js +52 -46
  18. package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
  19. package/cjs/app/observer/shadow_root_observer.js +3 -3
  20. package/cjs/app/observer/top_observer.d.ts +11 -2
  21. package/cjs/app/observer/top_observer.js +52 -23
  22. package/cjs/app/sanitizer.d.ts +1 -1
  23. package/cjs/app/sanitizer.js +5 -5
  24. package/cjs/app/session.d.ts +18 -2
  25. package/cjs/app/session.js +55 -6
  26. package/cjs/app/ticker.d.ts +1 -1
  27. package/cjs/common/{webworker.d.ts → interaction.d.ts} +5 -5
  28. package/cjs/common/{types.js → interaction.js} +0 -0
  29. package/cjs/common/messages.gen.d.ts +382 -0
  30. package/cjs/common/messages.gen.js +62 -0
  31. package/cjs/index.d.ts +10 -10
  32. package/cjs/index.js +42 -37
  33. package/cjs/modules/adoptedStyleSheets.d.ts +2 -0
  34. package/cjs/modules/adoptedStyleSheets.js +127 -0
  35. package/cjs/modules/connection.d.ts +1 -1
  36. package/cjs/modules/connection.js +2 -2
  37. package/cjs/modules/console.d.ts +1 -1
  38. package/cjs/modules/console.js +7 -21
  39. package/cjs/modules/cssrules.d.ts +1 -1
  40. package/cjs/modules/cssrules.js +18 -14
  41. package/cjs/modules/exception.d.ts +3 -3
  42. package/cjs/modules/exception.js +25 -20
  43. package/cjs/modules/img.d.ts +1 -1
  44. package/cjs/modules/img.js +39 -26
  45. package/cjs/modules/input.d.ts +1 -1
  46. package/cjs/modules/input.js +35 -31
  47. package/cjs/modules/mouse.d.ts +1 -1
  48. package/cjs/modules/mouse.js +50 -43
  49. package/cjs/modules/performance.d.ts +1 -1
  50. package/cjs/modules/performance.js +2 -2
  51. package/cjs/modules/scroll.d.ts +1 -1
  52. package/cjs/modules/scroll.js +16 -7
  53. package/cjs/modules/timing.d.ts +1 -1
  54. package/cjs/modules/timing.js +14 -26
  55. package/cjs/modules/viewport.d.ts +1 -1
  56. package/cjs/modules/viewport.js +4 -4
  57. package/cjs/utils.js +7 -7
  58. package/cjs/vendors/finder/finder.js +53 -48
  59. package/lib/app/guards.d.ts +2 -1
  60. package/lib/app/guards.js +4 -2
  61. package/lib/app/index.d.ts +24 -22
  62. package/lib/app/index.js +93 -93
  63. package/lib/app/logger.js +6 -3
  64. package/lib/app/messages.d.ts +52 -0
  65. package/lib/app/messages.gen.d.ts +57 -0
  66. package/lib/app/messages.gen.js +435 -0
  67. package/lib/app/messages.js +182 -0
  68. package/lib/app/nodes.d.ts +1 -1
  69. package/lib/app/nodes.js +4 -7
  70. package/lib/app/observer/iframe_observer.d.ts +1 -1
  71. package/lib/app/observer/iframe_observer.js +3 -3
  72. package/lib/app/observer/observer.d.ts +2 -2
  73. package/lib/app/observer/observer.js +53 -47
  74. package/lib/app/observer/shadow_root_observer.d.ts +1 -1
  75. package/lib/app/observer/shadow_root_observer.js +3 -3
  76. package/lib/app/observer/top_observer.d.ts +11 -2
  77. package/lib/app/observer/top_observer.js +56 -27
  78. package/lib/app/sanitizer.d.ts +1 -1
  79. package/lib/app/sanitizer.js +7 -7
  80. package/lib/app/session.d.ts +18 -2
  81. package/lib/app/session.js +55 -6
  82. package/lib/app/ticker.d.ts +1 -1
  83. package/lib/common/{webworker.d.ts → interaction.d.ts} +5 -5
  84. package/lib/common/{types.js → interaction.js} +0 -0
  85. package/lib/common/messages.gen.d.ts +382 -0
  86. package/lib/common/messages.gen.js +59 -0
  87. package/lib/common/tsconfig.tsbuildinfo +1 -1
  88. package/lib/index.d.ts +10 -10
  89. package/lib/index.js +55 -50
  90. package/lib/modules/adoptedStyleSheets.d.ts +2 -0
  91. package/lib/modules/adoptedStyleSheets.js +124 -0
  92. package/lib/modules/connection.d.ts +1 -1
  93. package/lib/modules/connection.js +2 -2
  94. package/lib/modules/console.d.ts +1 -1
  95. package/lib/modules/console.js +8 -22
  96. package/lib/modules/cssrules.d.ts +1 -1
  97. package/lib/modules/cssrules.js +19 -15
  98. package/lib/modules/exception.d.ts +3 -3
  99. package/lib/modules/exception.js +25 -20
  100. package/lib/modules/img.d.ts +1 -1
  101. package/lib/modules/img.js +41 -28
  102. package/lib/modules/input.d.ts +1 -1
  103. package/lib/modules/input.js +37 -33
  104. package/lib/modules/mouse.d.ts +1 -1
  105. package/lib/modules/mouse.js +53 -46
  106. package/lib/modules/performance.d.ts +1 -1
  107. package/lib/modules/performance.js +3 -3
  108. package/lib/modules/scroll.d.ts +1 -1
  109. package/lib/modules/scroll.js +17 -8
  110. package/lib/modules/timing.d.ts +1 -1
  111. package/lib/modules/timing.js +16 -28
  112. package/lib/modules/viewport.d.ts +1 -1
  113. package/lib/modules/viewport.js +4 -4
  114. package/lib/utils.js +7 -7
  115. package/lib/vendors/finder/finder.js +53 -48
  116. package/package.json +27 -10
  117. package/cjs/common/messages.d.ts +0 -444
  118. package/cjs/common/messages.js +0 -794
  119. package/cjs/common/types.d.ts +0 -9
  120. package/cjs/common/webworker.js +0 -2
  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,235 @@
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
+ const Messages = require("../common/messages.gen.js");
6
+ function BatchMetadata(version, pageNo, firstIndex, timestamp, location) {
7
+ return [Messages.Type.BatchMetadata, version, pageNo, firstIndex, timestamp, location];
8
+ }
9
+ exports.BatchMetadata = BatchMetadata;
10
+ function PartitionedMessage(partNo, partTotal) {
11
+ return [Messages.Type.PartitionedMessage, partNo, partTotal];
12
+ }
13
+ exports.PartitionedMessage = PartitionedMessage;
14
+ function Timestamp(timestamp) {
15
+ return [Messages.Type.Timestamp, timestamp];
16
+ }
17
+ exports.Timestamp = Timestamp;
18
+ function SetPageLocation(url, referrer, navigationStart) {
19
+ return [Messages.Type.SetPageLocation, url, referrer, navigationStart];
20
+ }
21
+ exports.SetPageLocation = SetPageLocation;
22
+ function SetViewportSize(width, height) {
23
+ return [Messages.Type.SetViewportSize, width, height];
24
+ }
25
+ exports.SetViewportSize = SetViewportSize;
26
+ function SetViewportScroll(x, y) {
27
+ return [Messages.Type.SetViewportScroll, x, y];
28
+ }
29
+ exports.SetViewportScroll = SetViewportScroll;
30
+ function CreateDocument() {
31
+ return [Messages.Type.CreateDocument];
32
+ }
33
+ exports.CreateDocument = CreateDocument;
34
+ function CreateElementNode(id, parentID, index, tag, svg) {
35
+ return [Messages.Type.CreateElementNode, id, parentID, index, tag, svg];
36
+ }
37
+ exports.CreateElementNode = CreateElementNode;
38
+ function CreateTextNode(id, parentID, index) {
39
+ return [Messages.Type.CreateTextNode, id, parentID, index];
40
+ }
41
+ exports.CreateTextNode = CreateTextNode;
42
+ function MoveNode(id, parentID, index) {
43
+ return [Messages.Type.MoveNode, id, parentID, index];
44
+ }
45
+ exports.MoveNode = MoveNode;
46
+ function RemoveNode(id) {
47
+ return [Messages.Type.RemoveNode, id];
48
+ }
49
+ exports.RemoveNode = RemoveNode;
50
+ function SetNodeAttribute(id, name, value) {
51
+ return [Messages.Type.SetNodeAttribute, id, name, value];
52
+ }
53
+ exports.SetNodeAttribute = SetNodeAttribute;
54
+ function RemoveNodeAttribute(id, name) {
55
+ return [Messages.Type.RemoveNodeAttribute, id, name];
56
+ }
57
+ exports.RemoveNodeAttribute = RemoveNodeAttribute;
58
+ function SetNodeData(id, data) {
59
+ return [Messages.Type.SetNodeData, id, data];
60
+ }
61
+ exports.SetNodeData = SetNodeData;
62
+ function SetNodeScroll(id, x, y) {
63
+ return [Messages.Type.SetNodeScroll, id, x, y];
64
+ }
65
+ exports.SetNodeScroll = SetNodeScroll;
66
+ function SetInputTarget(id, label) {
67
+ return [Messages.Type.SetInputTarget, id, label];
68
+ }
69
+ exports.SetInputTarget = SetInputTarget;
70
+ function SetInputValue(id, value, mask) {
71
+ return [Messages.Type.SetInputValue, id, value, mask];
72
+ }
73
+ exports.SetInputValue = SetInputValue;
74
+ function SetInputChecked(id, checked) {
75
+ return [Messages.Type.SetInputChecked, id, checked];
76
+ }
77
+ exports.SetInputChecked = SetInputChecked;
78
+ function MouseMove(x, y) {
79
+ return [Messages.Type.MouseMove, x, y];
80
+ }
81
+ exports.MouseMove = MouseMove;
82
+ function ConsoleLog(level, value) {
83
+ return [Messages.Type.ConsoleLog, level, value];
84
+ }
85
+ exports.ConsoleLog = ConsoleLog;
86
+ function PageLoadTiming(requestStart, responseStart, responseEnd, domContentLoadedEventStart, domContentLoadedEventEnd, loadEventStart, loadEventEnd, firstPaint, firstContentfulPaint) {
87
+ return [
88
+ Messages.Type.PageLoadTiming,
89
+ requestStart,
90
+ responseStart,
91
+ responseEnd,
92
+ domContentLoadedEventStart,
93
+ domContentLoadedEventEnd,
94
+ loadEventStart,
95
+ loadEventEnd,
96
+ firstPaint,
97
+ firstContentfulPaint,
98
+ ];
99
+ }
100
+ exports.PageLoadTiming = PageLoadTiming;
101
+ function PageRenderTiming(speedIndex, visuallyComplete, timeToInteractive) {
102
+ return [Messages.Type.PageRenderTiming, speedIndex, visuallyComplete, timeToInteractive];
103
+ }
104
+ exports.PageRenderTiming = PageRenderTiming;
105
+ function JSException(name, message, payload) {
106
+ return [Messages.Type.JSException, name, message, payload];
107
+ }
108
+ exports.JSException = JSException;
109
+ function RawCustomEvent(name, payload) {
110
+ return [Messages.Type.RawCustomEvent, name, payload];
111
+ }
112
+ exports.RawCustomEvent = RawCustomEvent;
113
+ function UserID(id) {
114
+ return [Messages.Type.UserID, id];
115
+ }
116
+ exports.UserID = UserID;
117
+ function UserAnonymousID(id) {
118
+ return [Messages.Type.UserAnonymousID, id];
119
+ }
120
+ exports.UserAnonymousID = UserAnonymousID;
121
+ function Metadata(key, value) {
122
+ return [Messages.Type.Metadata, key, value];
123
+ }
124
+ exports.Metadata = Metadata;
125
+ function CSSInsertRule(id, rule, index) {
126
+ return [Messages.Type.CSSInsertRule, id, rule, index];
127
+ }
128
+ exports.CSSInsertRule = CSSInsertRule;
129
+ function CSSDeleteRule(id, index) {
130
+ return [Messages.Type.CSSDeleteRule, id, index];
131
+ }
132
+ exports.CSSDeleteRule = CSSDeleteRule;
133
+ function Fetch(method, url, request, response, status, timestamp, duration) {
134
+ return [Messages.Type.Fetch, method, url, request, response, status, timestamp, duration];
135
+ }
136
+ exports.Fetch = Fetch;
137
+ function Profiler(name, duration, args, result) {
138
+ return [Messages.Type.Profiler, name, duration, args, result];
139
+ }
140
+ exports.Profiler = Profiler;
141
+ function OTable(key, value) {
142
+ return [Messages.Type.OTable, key, value];
143
+ }
144
+ exports.OTable = OTable;
145
+ function StateAction(type) {
146
+ return [Messages.Type.StateAction, type];
147
+ }
148
+ exports.StateAction = StateAction;
149
+ function Redux(action, state, duration) {
150
+ return [Messages.Type.Redux, action, state, duration];
151
+ }
152
+ exports.Redux = Redux;
153
+ function Vuex(mutation, state) {
154
+ return [Messages.Type.Vuex, mutation, state];
155
+ }
156
+ exports.Vuex = Vuex;
157
+ function MobX(type, payload) {
158
+ return [Messages.Type.MobX, type, payload];
159
+ }
160
+ exports.MobX = MobX;
161
+ function NgRx(action, state, duration) {
162
+ return [Messages.Type.NgRx, action, state, duration];
163
+ }
164
+ exports.NgRx = NgRx;
165
+ function GraphQL(operationKind, operationName, variables, response) {
166
+ return [Messages.Type.GraphQL, operationKind, operationName, variables, response];
167
+ }
168
+ exports.GraphQL = GraphQL;
169
+ function PerformanceTrack(frames, ticks, totalJSHeapSize, usedJSHeapSize) {
170
+ return [Messages.Type.PerformanceTrack, frames, ticks, totalJSHeapSize, usedJSHeapSize];
171
+ }
172
+ exports.PerformanceTrack = PerformanceTrack;
173
+ function ResourceTiming(timestamp, duration, ttfb, headerSize, encodedBodySize, decodedBodySize, url, initiator) {
174
+ return [
175
+ Messages.Type.ResourceTiming,
176
+ timestamp,
177
+ duration,
178
+ ttfb,
179
+ headerSize,
180
+ encodedBodySize,
181
+ decodedBodySize,
182
+ url,
183
+ initiator,
184
+ ];
185
+ }
186
+ exports.ResourceTiming = ResourceTiming;
187
+ function ConnectionInformation(downlink, type) {
188
+ return [Messages.Type.ConnectionInformation, downlink, type];
189
+ }
190
+ exports.ConnectionInformation = ConnectionInformation;
191
+ function SetPageVisibility(hidden) {
192
+ return [Messages.Type.SetPageVisibility, hidden];
193
+ }
194
+ exports.SetPageVisibility = SetPageVisibility;
195
+ function LongTask(timestamp, duration, context, containerType, containerSrc, containerId, containerName) {
196
+ return [
197
+ Messages.Type.LongTask,
198
+ timestamp,
199
+ duration,
200
+ context,
201
+ containerType,
202
+ containerSrc,
203
+ containerId,
204
+ containerName,
205
+ ];
206
+ }
207
+ exports.LongTask = LongTask;
208
+ function SetNodeAttributeURLBased(id, name, value, baseURL) {
209
+ return [Messages.Type.SetNodeAttributeURLBased, id, name, value, baseURL];
210
+ }
211
+ exports.SetNodeAttributeURLBased = SetNodeAttributeURLBased;
212
+ function SetCSSDataURLBased(id, data, baseURL) {
213
+ return [Messages.Type.SetCSSDataURLBased, id, data, baseURL];
214
+ }
215
+ exports.SetCSSDataURLBased = SetCSSDataURLBased;
216
+ function TechnicalInfo(type, value) {
217
+ return [Messages.Type.TechnicalInfo, type, value];
218
+ }
219
+ exports.TechnicalInfo = TechnicalInfo;
220
+ function CustomIssue(name, payload) {
221
+ return [Messages.Type.CustomIssue, name, payload];
222
+ }
223
+ exports.CustomIssue = CustomIssue;
224
+ function CSSInsertRuleURLBased(id, rule, index, baseURL) {
225
+ return [Messages.Type.CSSInsertRuleURLBased, id, rule, index, baseURL];
226
+ }
227
+ exports.CSSInsertRuleURLBased = CSSInsertRuleURLBased;
228
+ function MouseClick(id, hesitationTime, label, selector) {
229
+ return [Messages.Type.MouseClick, id, hesitationTime, label, selector];
230
+ }
231
+ exports.MouseClick = MouseClick;
232
+ function CreateIFrameDocument(frameID, id) {
233
+ return [Messages.Type.CreateIFrameDocument, frameID, id];
234
+ }
235
+ exports.CreateIFrameDocument = CreateIFrameDocument;
@@ -12,7 +12,7 @@ export default class Nodes {
12
12
  cleanTree(): void;
13
13
  callNodeCallbacks(node: Node, isStart: boolean): void;
14
14
  getID(node: Node): number | undefined;
15
- getNode(id: number): Node | undefined;
15
+ getNode(id: number): void | Node;
16
16
  clear(): void;
17
17
  }
18
18
  export {};
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) {
@@ -38,7 +40,7 @@ class Nodes {
38
40
  const id = node[this.node_id];
39
41
  if (id !== undefined) {
40
42
  delete node[this.node_id];
41
- this.nodes[id] = undefined;
43
+ delete this.nodes[id];
42
44
  const listeners = this.elementListeners.get(id);
43
45
  if (listeners !== undefined) {
44
46
  this.elementListeners.delete(id);
@@ -54,13 +56,8 @@ class Nodes {
54
56
  // performance test: 3ms for 30k nodes with 17k dead ones
55
57
  for (let i = 0; i < this.nodes.length; i++) {
56
58
  const node = this.nodes[i];
57
- if (node === undefined) {
58
- delete this.nodes[i];
59
- continue;
60
- }
61
- if (!document.contains(node)) {
59
+ if (node && !document.contains(node)) {
62
60
  this.unregisterNode(node);
63
- delete this.nodes[i];
64
61
  }
65
62
  }
66
63
  }
@@ -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;
@@ -14,7 +14,7 @@ export default abstract class Observer {
14
14
  private sendNodeData;
15
15
  private bindNode;
16
16
  private bindTree;
17
- private unbindNode;
17
+ private unbindTree;
18
18
  private _commitNode;
19
19
  private commitNode;
20
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,65 +125,76 @@ 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
- bindNode(node, isRemove = false) {
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?
167
- this.recents.set(id, isRemove ? RecentsType.RemovedChild : RecentsType.Removed);
160
+ else if (this.recents.get(id) !== RecentsType.New) {
161
+ this.recents.set(id, RecentsType.Removed);
168
162
  }
169
163
  }
170
- bindTree(node, isRemove = false) {
164
+ bindTree(node) {
171
165
  if (!isObservable(node)) {
172
166
  return;
173
167
  }
174
168
  this.bindNode(node);
175
169
  const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
176
- acceptNode: (node) => isIgnored(node)
177
- || (this.app.nodes.getID(node) !== undefined && !isRemove)
170
+ acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) !== undefined
178
171
  ? NodeFilter.FILTER_REJECT
179
172
  : NodeFilter.FILTER_ACCEPT,
180
173
  },
181
174
  // @ts-ignore
182
175
  false);
183
176
  while (walker.nextNode()) {
184
- this.bindNode(walker.currentNode, isRemove);
177
+ this.bindNode(walker.currentNode);
185
178
  }
186
179
  }
187
- unbindNode(node) {
180
+ unbindTree(node) {
188
181
  const id = this.app.nodes.unregisterNode(node);
189
182
  if (id !== undefined && this.recents.get(id) === RecentsType.Removed) {
190
- 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)
191
197
  }
192
- return id;
193
198
  }
194
199
  // A top-consumption function on the infinite lists test. (~1% of performance resources)
195
200
  _commitNode(id, node) {
@@ -201,20 +206,20 @@ class Observer {
201
206
  // Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
202
207
  // TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
203
208
  // TODO: Clean the logic (though now it workd fine)
204
- if (!(0, guards_js_1.hasTag)(node, "HTML") || !this.isTopContext) {
209
+ if (!(0, guards_js_1.hasTag)(node, 'HTML') || !this.isTopContext) {
205
210
  if (parent === null) {
206
211
  // Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
207
- // That shouldn't affect the visual rendering ( should it? )
208
- this.unbindNode(node);
212
+ // That shouldn't affect the visual rendering ( should it? maybe when transition applied? )
213
+ this.unbindTree(node);
209
214
  return false;
210
215
  }
211
216
  parentID = this.app.nodes.getID(parent);
212
217
  if (parentID === undefined) {
213
- this.unbindNode(node);
218
+ this.unbindTree(node);
214
219
  return false;
215
220
  }
216
221
  if (!this.commitNode(parentID)) {
217
- this.unbindNode(node);
222
+ this.unbindTree(node);
218
223
  return false;
219
224
  }
220
225
  this.app.sanitizer.handleNode(id, parentID, node);
@@ -253,7 +258,7 @@ class Observer {
253
258
  el.style.width = width + 'px';
254
259
  el.style.height = height + 'px';
255
260
  }
256
- 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)));
257
262
  }
258
263
  for (let i = 0; i < el.attributes.length; i++) {
259
264
  const attr = el.attributes[i];
@@ -262,13 +267,13 @@ class Observer {
262
267
  }
263
268
  else if ((0, guards_js_1.isTextNode)(node)) {
264
269
  // for text node id != 0, hence parentID !== undefined and parent is Element
265
- this.app.send(new messages_js_1.CreateTextNode(id, parentID, index));
270
+ this.app.send((0, messages_gen_js_1.CreateTextNode)(id, parentID, index));
266
271
  this.sendNodeData(id, parent, node.data);
267
272
  }
268
273
  return true;
269
274
  }
270
275
  if (recentsType === RecentsType.Removed && parentID !== undefined) {
271
- this.app.send(new messages_js_1.MoveNode(id, parentID, index));
276
+ this.app.send((0, messages_gen_js_1.MoveNode)(id, parentID, index));
272
277
  }
273
278
  const attr = this.attributesMap.get(id);
274
279
  if (attr !== undefined) {
@@ -309,7 +314,8 @@ class Observer {
309
314
  });
310
315
  this.clear();
311
316
  }
312
- // 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)
313
319
  observeRoot(node, beforeCommit, nodeToBind = node) {
314
320
  this.observer.observe(node, {
315
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,19 @@
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 ContextCallback = (context: Window & typeof globalThis) => void;
7
+ declare type Offset = {
8
+ top: number;
9
+ left: number;
10
+ };
6
11
  export default class TopObserver extends Observer {
7
12
  private readonly options;
8
13
  constructor(app: App, options: Partial<Options>);
14
+ private readonly contextCallbacks;
15
+ attachContextCallback(cb: ContextCallback): void;
16
+ getDocumentOffset(doc: Document): Offset;
9
17
  private iframeObservers;
10
18
  private handleIframe;
11
19
  private shadowRootObservers;
@@ -13,3 +21,4 @@ export default class TopObserver extends Observer {
13
21
  observe(): void;
14
22
  disconnect(): void;
15
23
  }
24
+ export {};