@openreplay/tracker 3.6.3 → 4.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 (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 +101 -83
  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 +109 -91
  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
package/lib/index.js CHANGED
@@ -1,20 +1,21 @@
1
- import App, { DEFAULT_INGEST_POINT } from "./app/index.js";
1
+ import App, { DEFAULT_INGEST_POINT } from './app/index.js';
2
2
  export { default as App } from './app/index.js';
3
- import { UserAnonymousID, RawCustomEvent, CustomIssue } from "./common/messages.js";
4
- import * as _Messages from "./common/messages.js";
3
+ import { UserAnonymousID, RawCustomEvent, CustomIssue } from './app/messages.gen.js';
4
+ import * as _Messages from './app/messages.gen.js';
5
5
  export const Messages = _Messages;
6
- import Connection from "./modules/connection.js";
7
- import Console from "./modules/console.js";
8
- import Exception, { getExceptionMessageFromEvent, getExceptionMessage } from "./modules/exception.js";
9
- import Img from "./modules/img.js";
10
- import Input from "./modules/input.js";
11
- import Mouse from "./modules/mouse.js";
12
- import Timing from "./modules/timing.js";
13
- import Performance from "./modules/performance.js";
14
- import Scroll from "./modules/scroll.js";
15
- import Viewport from "./modules/viewport.js";
16
- import CSSRules from "./modules/cssrules.js";
17
- import { IN_BROWSER, deprecationWarn, DOCS_HOST } from "./utils.js";
6
+ import Connection from './modules/connection.js';
7
+ import Console from './modules/console.js';
8
+ import Exception, { getExceptionMessageFromEvent, getExceptionMessage, } from './modules/exception.js';
9
+ import Img from './modules/img.js';
10
+ import Input from './modules/input.js';
11
+ import Mouse from './modules/mouse.js';
12
+ import Timing from './modules/timing.js';
13
+ import Performance from './modules/performance.js';
14
+ import Scroll from './modules/scroll.js';
15
+ import Viewport from './modules/viewport.js';
16
+ import CSSRules from './modules/cssrules.js';
17
+ import AdoptedStyleSheets from './modules/adoptedStyleSheets.js';
18
+ import { IN_BROWSER, deprecationWarn, DOCS_HOST } from './utils.js';
18
19
  const DOCS_SETUP = '/installation/setup-or';
19
20
  function processOptions(obj) {
20
21
  if (obj == null) {
@@ -23,22 +24,23 @@ function processOptions(obj) {
23
24
  }
24
25
  if (typeof obj.projectKey !== 'string') {
25
26
  if (typeof obj.projectKey !== 'number') {
26
- if (typeof obj.projectID !== 'number') { // Back compatability
27
+ if (typeof obj.projectID !== 'number') {
28
+ // Back compatability
27
29
  console.error(`OpenReplay: projectKey is missing or wrong type (string is expected). Please, check ${DOCS_HOST}${DOCS_SETUP} for more information.`);
28
30
  return false;
29
31
  }
30
32
  else {
31
33
  obj.projectKey = obj.projectID.toString();
32
- deprecationWarn("`projectID` option", "`projectKey` option", DOCS_SETUP);
34
+ deprecationWarn('`projectID` option', '`projectKey` option', DOCS_SETUP);
33
35
  }
34
36
  }
35
37
  else {
36
- console.warn("OpenReplay: projectKey is expected to have a string type.");
38
+ console.warn('OpenReplay: projectKey is expected to have a string type.');
37
39
  obj.projectKey = obj.projectKey.toString();
38
40
  }
39
41
  }
40
- if (typeof obj.sessionToken !== 'string' && obj.sessionToken != null) {
41
- console.warn(`OpenReplay: invalid options argument type. Please, check documentation on ${DOCS_HOST}${DOCS_SETUP}`);
42
+ if (obj.sessionToken != null) {
43
+ deprecationWarn('`sessionToken` option', '`sessionHash` start() option', '/');
42
44
  }
43
45
  return true;
44
46
  }
@@ -65,31 +67,33 @@ export default class API {
65
67
  return;
66
68
  }
67
69
  if (window.__OPENREPLAY__) {
68
- console.error("OpenReplay: one tracker instance has been initialised already");
70
+ console.error('OpenReplay: one tracker instance has been initialised already');
69
71
  return;
70
72
  }
71
73
  if (!options.__DISABLE_SECURE_MODE && location.protocol !== 'https:') {
72
- console.error("OpenReplay: Your website must be publicly accessible and running on SSL in order for OpenReplay to properly capture and replay the user session. You can disable this check by setting `__DISABLE_SECURE_MODE` option to `true` if you are testing in localhost. Keep in mind, that asset files on a local machine are not available to the outside world. This might affect tracking if you use css files.");
74
+ console.error('OpenReplay: Your website must be publicly accessible and running on SSL in order for OpenReplay to properly capture and replay the user session. You can disable this check by setting `__DISABLE_SECURE_MODE` option to `true` if you are testing in localhost. Keep in mind, that asset files on a local machine are not available to the outside world. This might affect tracking if you use css files.');
73
75
  return;
74
76
  }
75
77
  const doNotTrack = options.respectDoNotTrack &&
76
- (navigator.doNotTrack == '1'
78
+ (navigator.doNotTrack == '1' ||
77
79
  // @ts-ignore
78
- || window.doNotTrack == '1');
79
- const app = this.app = doNotTrack ||
80
- !('Map' in window) ||
81
- !('Set' in window) ||
82
- !('MutationObserver' in window) ||
83
- !('performance' in window) ||
84
- !('timing' in performance) ||
85
- !('startsWith' in String.prototype) ||
86
- !('Blob' in window) ||
87
- !('Worker' in window)
88
- ? null
89
- : new App(options.projectKey, options.sessionToken, options);
80
+ window.doNotTrack == '1');
81
+ const app = (this.app =
82
+ doNotTrack ||
83
+ !('Map' in window) ||
84
+ !('Set' in window) ||
85
+ !('MutationObserver' in window) ||
86
+ !('performance' in window) ||
87
+ !('timing' in performance) ||
88
+ !('startsWith' in String.prototype) ||
89
+ !('Blob' in window) ||
90
+ !('Worker' in window)
91
+ ? null
92
+ : new App(options.projectKey, options.sessionToken, options));
90
93
  if (app !== null) {
91
94
  Viewport(app);
92
95
  CSSRules(app);
96
+ AdoptedStyleSheets(app);
93
97
  Connection(app);
94
98
  Console(app, options);
95
99
  Exception(app, options);
@@ -119,11 +123,11 @@ export default class API {
119
123
  console.log("OpenReplay: browser doesn't support API required for tracking or doNotTrack is set to 1.");
120
124
  const req = new XMLHttpRequest();
121
125
  const orig = options.ingestPoint || DEFAULT_INGEST_POINT;
122
- req.open("POST", orig + "/v1/web/not-started");
126
+ req.open('POST', orig + '/v1/web/not-started');
123
127
  // no-cors issue only with text/plain or not-set Content-Type
124
128
  // req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
125
129
  req.send(JSON.stringify({
126
- trackerVersion: '3.6.3',
130
+ trackerVersion: '4.0.0',
127
131
  projectKey: options.projectKey,
128
132
  doNotTrack,
129
133
  // TODO: add precise reason (an exact API missing)
@@ -142,7 +146,7 @@ export default class API {
142
146
  start(startOpts) {
143
147
  if (!IN_BROWSER) {
144
148
  console.error(`OpenReplay: you are trying to start Tracker on a node.js environment. If you want to use OpenReplay with SSR, please, use componentDidMount or useEffect API for placing the \`tracker.start()\` line. Check documentation on ${DOCS_HOST}${DOCS_SETUP}`);
145
- return Promise.reject("Trying to start not in browser.");
149
+ return Promise.reject('Trying to start not in browser.');
146
150
  }
147
151
  if (this.app === null) {
148
152
  return Promise.reject("Browser doesn't support required api, or doNotTrack is active.");
@@ -154,7 +158,10 @@ export default class API {
154
158
  if (this.app === null) {
155
159
  return;
156
160
  }
157
- this.app.stop(true);
161
+ this.app.stop();
162
+ const sessionHash = this.app.session.getSessionHash();
163
+ this.app.session.reset();
164
+ return sessionHash;
158
165
  }
159
166
  getSessionToken() {
160
167
  if (this.app === null) {
@@ -169,36 +176,40 @@ export default class API {
169
176
  return this.app.getSessionID();
170
177
  }
171
178
  sessionID() {
172
- deprecationWarn("'sessionID' method", "'getSessionID' method", "/");
179
+ deprecationWarn("'sessionID' method", "'getSessionID' method", '/');
173
180
  return this.getSessionID();
174
181
  }
182
+ getSessionURL() {
183
+ if (this.app === null) {
184
+ return undefined;
185
+ }
186
+ return this.app.getSessionURL();
187
+ }
175
188
  setUserID(id) {
176
189
  if (typeof id === 'string' && this.app !== null) {
177
190
  this.app.session.setUserID(id);
178
191
  }
179
192
  }
180
193
  userID(id) {
181
- deprecationWarn("'userID' method", "'setUserID' method", "/");
194
+ deprecationWarn("'userID' method", "'setUserID' method", '/');
182
195
  this.setUserID(id);
183
196
  }
184
197
  setUserAnonymousID(id) {
185
198
  if (typeof id === 'string' && this.app !== null) {
186
- this.app.send(new UserAnonymousID(id));
199
+ this.app.send(UserAnonymousID(id));
187
200
  }
188
201
  }
189
202
  userAnonymousID(id) {
190
- deprecationWarn("'userAnonymousID' method", "'setUserAnonymousID' method", "/");
203
+ deprecationWarn("'userAnonymousID' method", "'setUserAnonymousID' method", '/');
191
204
  this.setUserAnonymousID(id);
192
205
  }
193
206
  setMetadata(key, value) {
194
- if (typeof key === 'string' &&
195
- typeof value === 'string' &&
196
- this.app !== null) {
207
+ if (typeof key === 'string' && typeof value === 'string' && this.app !== null) {
197
208
  this.app.session.setMetadata(key, value);
198
209
  }
199
210
  }
200
211
  metadata(key, value) {
201
- deprecationWarn("'metadata' method", "'setMetadata' method", "/");
212
+ deprecationWarn("'metadata' method", "'setMetadata' method", '/');
202
213
  this.setMetadata(key, value);
203
214
  }
204
215
  event(key, payload, issue = false) {
@@ -213,7 +224,7 @@ export default class API {
213
224
  catch (e) {
214
225
  return;
215
226
  }
216
- this.app.send(new RawCustomEvent(key, payload));
227
+ this.app.send(RawCustomEvent(key, payload));
217
228
  }
218
229
  }
219
230
  }
@@ -225,7 +236,7 @@ export default class API {
225
236
  catch (e) {
226
237
  return;
227
238
  }
228
- this.app.send(new CustomIssue(key, payload));
239
+ this.app.send(CustomIssue(key, payload));
229
240
  }
230
241
  }
231
242
  }
@@ -0,0 +1,2 @@
1
+ import type App from '../app/index.js';
2
+ export default function (app: App | null): void;
@@ -0,0 +1,124 @@
1
+ import { TechnicalInfo, AdoptedSSReplaceURLBased, AdoptedSSInsertRuleURLBased, AdoptedSSDeleteRule, AdoptedSSAddOwner, AdoptedSSRemoveOwner, } from '../app/messages.gen.js';
2
+ import { isRootNode } from '../app/guards.js';
3
+ function hasAdoptedSS(node) {
4
+ return (isRootNode(node) &&
5
+ // @ts-ignore
6
+ !!node.adoptedStyleSheets);
7
+ }
8
+ export default function (app) {
9
+ if (app === null) {
10
+ return;
11
+ }
12
+ if (!hasAdoptedSS(document)) {
13
+ app.attachStartCallback(() => {
14
+ // MBTODO: pre-start sendQueue app
15
+ app.send(TechnicalInfo('no_adopted_stylesheets', ''));
16
+ });
17
+ return;
18
+ }
19
+ let nextID = 0xf;
20
+ const styleSheetIDMap = new Map();
21
+ const adoptedStyleSheetsOwnings = new Map();
22
+ const updateAdoptedStyleSheets = (root) => {
23
+ let nodeID = app.nodes.getID(root);
24
+ if (root === document) {
25
+ nodeID = 0; // main document doesn't have nodeID. ID count starts from the documentElement
26
+ }
27
+ if (!nodeID) {
28
+ return;
29
+ }
30
+ let pastOwning = adoptedStyleSheetsOwnings.get(nodeID);
31
+ if (!pastOwning) {
32
+ pastOwning = [];
33
+ }
34
+ const nowOwning = [];
35
+ const styleSheets = root.adoptedStyleSheets;
36
+ for (const s of styleSheets) {
37
+ let sheetID = styleSheetIDMap.get(s);
38
+ const init = !sheetID;
39
+ if (!sheetID) {
40
+ sheetID = ++nextID;
41
+ }
42
+ nowOwning.push(sheetID);
43
+ if (!pastOwning.includes(sheetID)) {
44
+ app.send(AdoptedSSAddOwner(sheetID, nodeID));
45
+ }
46
+ if (init) {
47
+ const rules = s.cssRules;
48
+ for (let i = 0; i < rules.length; i++) {
49
+ app.send(AdoptedSSInsertRuleURLBased(sheetID, rules[i].cssText, i, app.getBaseHref()));
50
+ }
51
+ }
52
+ }
53
+ for (const sheetID of pastOwning) {
54
+ if (!nowOwning.includes(sheetID)) {
55
+ app.send(AdoptedSSRemoveOwner(sheetID, nodeID));
56
+ }
57
+ }
58
+ adoptedStyleSheetsOwnings.set(nodeID, nowOwning);
59
+ };
60
+ function patchAdoptedStyleSheets(prototype) {
61
+ const nativeAdoptedStyleSheetsDescriptor = Object.getOwnPropertyDescriptor(prototype, 'adoptedStyleSheets');
62
+ if (nativeAdoptedStyleSheetsDescriptor) {
63
+ Object.defineProperty(prototype, 'adoptedStyleSheets', Object.assign(Object.assign({}, nativeAdoptedStyleSheetsDescriptor), { set: function (value) {
64
+ // @ts-ignore
65
+ const retVal = nativeAdoptedStyleSheetsDescriptor.set.call(this, value);
66
+ updateAdoptedStyleSheets(this);
67
+ return retVal;
68
+ } }));
69
+ }
70
+ }
71
+ const patchContext = (context) => {
72
+ patchAdoptedStyleSheets(context.Document.prototype);
73
+ patchAdoptedStyleSheets(context.ShadowRoot.prototype);
74
+ //@ts-ignore TODO: configure ts (use necessary lib)
75
+ const { insertRule, deleteRule, replace, replaceSync } = context.CSSStyleSheet.prototype;
76
+ //@ts-ignore
77
+ context.CSSStyleSheet.prototype.replace = function (text) {
78
+ return replace.call(this, text).then((sheet) => {
79
+ const sheetID = styleSheetIDMap.get(this);
80
+ if (sheetID) {
81
+ app.send(AdoptedSSReplaceURLBased(sheetID, text, app.getBaseHref()));
82
+ }
83
+ return sheet;
84
+ });
85
+ };
86
+ //@ts-ignore
87
+ context.CSSStyleSheet.prototype.replaceSync = function (text) {
88
+ const sheetID = styleSheetIDMap.get(this);
89
+ if (sheetID) {
90
+ app.send(AdoptedSSReplaceURLBased(sheetID, text, app.getBaseHref()));
91
+ }
92
+ return replaceSync.call(this, text);
93
+ };
94
+ context.CSSStyleSheet.prototype.insertRule = function (rule, index = 0) {
95
+ const sheetID = styleSheetIDMap.get(this);
96
+ if (sheetID) {
97
+ app.send(AdoptedSSInsertRuleURLBased(sheetID, rule, index, app.getBaseHref()));
98
+ }
99
+ return insertRule.call(this, rule, index);
100
+ };
101
+ context.CSSStyleSheet.prototype.deleteRule = function (index) {
102
+ const sheetID = styleSheetIDMap.get(this);
103
+ if (sheetID) {
104
+ app.send(AdoptedSSDeleteRule(sheetID, index));
105
+ }
106
+ return deleteRule.call(this, index);
107
+ };
108
+ };
109
+ patchContext(window);
110
+ app.observer.attachContextCallback(patchContext);
111
+ app.attachStopCallback(() => {
112
+ styleSheetIDMap.clear();
113
+ adoptedStyleSheetsOwnings.clear();
114
+ });
115
+ // So far main Document is not triggered with nodeCallbacks
116
+ app.attachStartCallback(() => {
117
+ updateAdoptedStyleSheets(document);
118
+ });
119
+ app.nodes.attachNodeCallback((node) => {
120
+ if (hasAdoptedSS(node)) {
121
+ updateAdoptedStyleSheets(node);
122
+ }
123
+ });
124
+ }
@@ -1,2 +1,2 @@
1
- import App from "../app/index.js";
1
+ import App from '../app/index.js';
2
2
  export default function (app: App): void;
@@ -1,4 +1,4 @@
1
- import { ConnectionInformation } from "../common/messages.js";
1
+ import { ConnectionInformation } from '../app/messages.gen.js';
2
2
  export default function (app) {
3
3
  const connection = navigator.connection ||
4
4
  navigator.mozConnection ||
@@ -6,7 +6,7 @@ export default function (app) {
6
6
  if (connection === undefined) {
7
7
  return;
8
8
  }
9
- const sendConnectionInformation = () => app.send(new ConnectionInformation(Math.round(connection.downlink * 1000), connection.type || 'unknown'));
9
+ const sendConnectionInformation = () => app.send(ConnectionInformation(Math.round(connection.downlink * 1000), connection.type || 'unknown'));
10
10
  sendConnectionInformation();
11
11
  connection.addEventListener('change', sendConnectionInformation);
12
12
  }
@@ -1,4 +1,4 @@
1
- import type App from "../app/index.js";
1
+ import type App from '../app/index.js';
2
2
  export interface Options {
3
3
  consoleMethods: Array<string> | null;
4
4
  consoleThrottling: number;
@@ -1,6 +1,5 @@
1
- import { hasTag } from "../app/guards.js";
2
- import { IN_BROWSER } from "../utils.js";
3
- import { ConsoleLog } from "../common/messages.js";
1
+ import { IN_BROWSER } from '../utils.js';
2
+ import { ConsoleLog } from '../app/messages.gen.js';
4
3
  const printError = IN_BROWSER && 'InstallTrigger' in window // detect Firefox
5
4
  ? (e) => e.message + '\n' + e.stack
6
5
  : (e) => e.stack || e.message;
@@ -87,11 +86,10 @@ export default function (app, opts) {
87
86
  consoleMethods,
88
87
  consoleThrottling: 30,
89
88
  }, opts);
90
- if (!Array.isArray(options.consoleMethods) ||
91
- options.consoleMethods.length === 0) {
89
+ if (!Array.isArray(options.consoleMethods) || options.consoleMethods.length === 0) {
92
90
  return;
93
91
  }
94
- const sendConsoleLog = app.safe((level, args) => app.send(new ConsoleLog(level, printf(args))));
92
+ const sendConsoleLog = app.safe((level, args) => app.send(ConsoleLog(level, printf(args))));
95
93
  let n;
96
94
  const reset = () => {
97
95
  n = 0;
@@ -100,7 +98,7 @@ export default function (app, opts) {
100
98
  app.ticker.attach(reset, 33, false);
101
99
  const patchConsole = (console) => options.consoleMethods.forEach((method) => {
102
100
  if (consoleMethods.indexOf(method) === -1) {
103
- console.error(`OpenReplay: unsupported console method "${method}"`);
101
+ app.debug.error(`OpenReplay: unsupported console method "${method}"`);
104
102
  return;
105
103
  }
106
104
  const fn = console[method];
@@ -112,19 +110,7 @@ export default function (app, opts) {
112
110
  sendConsoleLog(method, args);
113
111
  };
114
112
  });
115
- patchConsole(window.console);
116
- app.nodes.attachNodeCallback(app.safe(node => {
117
- if (hasTag(node, "IFRAME")) { // TODO: newContextCallback
118
- let context = node.contentWindow;
119
- if (context) {
120
- patchConsole(context.console);
121
- }
122
- app.attachEventListener(node, "load", () => {
123
- if (node.contentWindow !== context) {
124
- context = node.contentWindow;
125
- patchConsole(context.console);
126
- }
127
- });
128
- }
129
- }));
113
+ const patchContext = app.safe((context) => patchConsole(context.console));
114
+ patchContext(window);
115
+ app.observer.attachContextCallback(patchContext);
130
116
  }
@@ -1,2 +1,2 @@
1
- import type App from "../app/index.js";
1
+ import type App from '../app/index.js';
2
2
  export default function (app: App | null): void;
@@ -1,37 +1,41 @@
1
- import { CSSInsertRuleURLBased, CSSDeleteRule, TechnicalInfo } from "../common/messages.js";
2
- import { hasTag } from "../app/guards.js";
1
+ import { CSSInsertRuleURLBased, CSSDeleteRule, TechnicalInfo } from '../app/messages.gen.js';
2
+ import { hasTag } from '../app/guards.js';
3
3
  export default function (app) {
4
4
  if (app === null) {
5
5
  return;
6
6
  }
7
7
  if (!window.CSSStyleSheet) {
8
- app.send(new TechnicalInfo("no_stylesheet_prototype_in_window", ""));
8
+ app.send(TechnicalInfo('no_stylesheet_prototype_in_window', ''));
9
9
  return;
10
10
  }
11
11
  const processOperation = app.safe((stylesheet, index, rule) => {
12
12
  const sendMessage = typeof rule === 'string'
13
- ? (nodeID) => app.send(new CSSInsertRuleURLBased(nodeID, rule, index, app.getBaseHref()))
14
- : (nodeID) => app.send(new CSSDeleteRule(nodeID, index));
13
+ ? (nodeID) => app.send(CSSInsertRuleURLBased(nodeID, rule, index, app.getBaseHref()))
14
+ : (nodeID) => app.send(CSSDeleteRule(nodeID, index));
15
15
  // TODO: Extend messages to maintain nested rules (CSSGroupingRule prototype, as well as CSSKeyframesRule)
16
16
  if (stylesheet.ownerNode == null) {
17
- throw new Error("Owner Node not found");
17
+ throw new Error('Owner Node not found');
18
18
  }
19
19
  const nodeID = app.nodes.getID(stylesheet.ownerNode);
20
20
  if (nodeID !== undefined) {
21
21
  sendMessage(nodeID);
22
22
  } // else error?
23
23
  });
24
- const { insertRule, deleteRule } = CSSStyleSheet.prototype;
25
- CSSStyleSheet.prototype.insertRule = function (rule, index = 0) {
26
- processOperation(this, index, rule);
27
- return insertRule.call(this, rule, index);
28
- };
29
- CSSStyleSheet.prototype.deleteRule = function (index) {
30
- processOperation(this, index);
31
- return deleteRule.call(this, index);
24
+ const patchContext = (context) => {
25
+ const { insertRule, deleteRule } = context.CSSStyleSheet.prototype;
26
+ context.CSSStyleSheet.prototype.insertRule = function (rule, index = 0) {
27
+ processOperation(this, index, rule);
28
+ return insertRule.call(this, rule, index);
29
+ };
30
+ context.CSSStyleSheet.prototype.deleteRule = function (index) {
31
+ processOperation(this, index);
32
+ return deleteRule.call(this, index);
33
+ };
32
34
  };
35
+ patchContext(window);
36
+ app.observer.attachContextCallback(patchContext);
33
37
  app.nodes.attachNodeCallback((node) => {
34
- if (!hasTag(node, "STYLE") || !node.sheet) {
38
+ if (!hasTag(node, 'STYLE') || !node.sheet) {
35
39
  return;
36
40
  }
37
41
  if (node.textContent !== null && node.textContent.trim().length > 0) {
@@ -1,5 +1,5 @@
1
- import type App from "../app/index.js";
2
- import type Message from "../common/messages.js";
1
+ import type App from '../app/index.js';
2
+ import type Message from '../app/messages.gen.js';
3
3
  export interface Options {
4
4
  captureExceptions: boolean;
5
5
  }
@@ -11,6 +11,6 @@ interface StackFrame {
11
11
  source?: string;
12
12
  }
13
13
  export declare function getExceptionMessage(error: Error, fallbackStack: Array<StackFrame>): Message;
14
- export declare function getExceptionMessageFromEvent(e: ErrorEvent | PromiseRejectionEvent): Message | null;
14
+ export declare function getExceptionMessageFromEvent(e: ErrorEvent | PromiseRejectionEvent, context?: typeof globalThis): Message | null;
15
15
  export default function (app: App, opts: Partial<Options>): void;
16
16
  export {};
@@ -1,24 +1,25 @@
1
- import { JSException } from "../common/messages.js";
1
+ import { JSException } from '../app/messages.gen.js';
2
2
  import ErrorStackParser from 'error-stack-parser';
3
3
  function getDefaultStack(e) {
4
- return [{
4
+ return [
5
+ {
5
6
  columnNumber: e.colno,
6
7
  lineNumber: e.lineno,
7
8
  fileName: e.filename,
8
- functionName: "",
9
- source: "",
10
- }];
9
+ functionName: '',
10
+ source: '',
11
+ },
12
+ ];
11
13
  }
12
14
  export function getExceptionMessage(error, fallbackStack) {
13
15
  let stack = fallbackStack;
14
16
  try {
15
17
  stack = ErrorStackParser.parse(error);
16
18
  }
17
- catch (e) {
18
- }
19
- return new JSException(error.name, error.message, JSON.stringify(stack));
19
+ catch (e) { }
20
+ return JSException(error.name, error.message, JSON.stringify(stack));
20
21
  }
21
- export function getExceptionMessageFromEvent(e) {
22
+ export function getExceptionMessageFromEvent(e, context = window) {
22
23
  if (e instanceof ErrorEvent) {
23
24
  if (e.error instanceof Error) {
24
25
  return getExceptionMessage(e.error, getDefaultStack(e));
@@ -29,10 +30,10 @@ export function getExceptionMessageFromEvent(e) {
29
30
  name = 'Error';
30
31
  message = e.message;
31
32
  }
32
- return new JSException(name, message, JSON.stringify(getDefaultStack(e)));
33
+ return JSException(name, message, JSON.stringify(getDefaultStack(e)));
33
34
  }
34
35
  }
35
- else if ('PromiseRejectionEvent' in window && e instanceof PromiseRejectionEvent) {
36
+ else if ('PromiseRejectionEvent' in context && e instanceof context.PromiseRejectionEvent) {
36
37
  if (e.reason instanceof Error) {
37
38
  return getExceptionMessage(e.reason, []);
38
39
  }
@@ -44,7 +45,7 @@ export function getExceptionMessageFromEvent(e) {
44
45
  catch (_) {
45
46
  message = String(e.reason);
46
47
  }
47
- return new JSException('Unhandled Promise Rejection', message, '[]');
48
+ return JSException('Unhandled Promise Rejection', message, '[]');
48
49
  }
49
50
  }
50
51
  return null;
@@ -53,14 +54,18 @@ export default function (app, opts) {
53
54
  const options = Object.assign({
54
55
  captureExceptions: true,
55
56
  }, opts);
56
- if (options.captureExceptions) {
57
- const handler = (e) => {
58
- const msg = getExceptionMessageFromEvent(e);
57
+ function patchContext(context) {
58
+ function handler(e) {
59
+ const msg = getExceptionMessageFromEvent(e, context);
59
60
  if (msg != null) {
60
61
  app.send(msg);
61
62
  }
62
- };
63
- app.attachEventListener(window, 'unhandledrejection', (e) => handler(e));
64
- app.attachEventListener(window, 'error', (e) => handler(e));
63
+ }
64
+ app.attachEventListener(context, 'unhandledrejection', handler);
65
+ app.attachEventListener(context, 'error', handler);
66
+ }
67
+ if (options.captureExceptions) {
68
+ app.observer.attachContextCallback(patchContext);
69
+ patchContext(window);
65
70
  }
66
71
  }
@@ -1,2 +1,2 @@
1
- import type App from "../app/index.js";
1
+ import type App from '../app/index.js';
2
2
  export default function (app: App): void;