@openreplay/tracker 16.4.3 → 16.4.4

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.
@@ -14,6 +14,7 @@ import type { Options as NetworkOptions } from './modules/network.js';
14
14
  import type { MouseHandlerOptions } from './modules/mouse.js';
15
15
  import type { SessionInfo } from './app/session.js';
16
16
  import type { CssRulesOptions } from './modules/cssrules.js';
17
+ import type { Options as ViewportOptions } from './modules/viewport.js';
17
18
  import type { StartOptions } from './app/index.js';
18
19
  import type { StartPromiseReturn } from './app/index.js';
19
20
  export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & InputOptions & PerformanceOptions & TimingOptions> & {
@@ -30,6 +31,7 @@ export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & I
30
31
  };
31
32
  __DISABLE_SECURE_MODE?: boolean;
32
33
  css: CssRulesOptions;
34
+ urls?: Partial<ViewportOptions>;
33
35
  };
34
36
  export default class API {
35
37
  readonly options: Partial<Options>;
@@ -1,2 +1,6 @@
1
1
  import type App from '../app/index.js';
2
- export default function (app: App): void;
2
+ export interface Options {
3
+ urlSanitizer?: (url: string) => string;
4
+ titleSanitizer?: (title: string) => string;
5
+ }
6
+ export default function (app: App, options?: Options): void;
package/dist/lib/entry.js CHANGED
@@ -5168,7 +5168,7 @@ class Session {
5168
5168
  }
5169
5169
  }
5170
5170
 
5171
- function wrap(callback, n) {
5171
+ function wrap$1(callback, n) {
5172
5172
  let t = 0;
5173
5173
  return () => {
5174
5174
  if (t++ >= n) {
@@ -5196,7 +5196,7 @@ class Ticker {
5196
5196
  if (useSafe) {
5197
5197
  callback = this.app.safe(callback);
5198
5198
  }
5199
- this.callbacks.unshift(n ? wrap(callback, n) : callback) - 1;
5199
+ this.callbacks.unshift(n ? wrap$1(callback, n) : callback) - 1;
5200
5200
  }
5201
5201
  start() {
5202
5202
  if (this.timer === null) {
@@ -5272,7 +5272,7 @@ class App {
5272
5272
  this.stopCallbacks = [];
5273
5273
  this.commitCallbacks = [];
5274
5274
  this.activityState = ActivityState.NotActive;
5275
- this.version = '16.4.3'; // TODO: version compatability check inside each plugin.
5275
+ this.version = '16.4.4'; // TODO: version compatability check inside each plugin.
5276
5276
  this.socketMode = false;
5277
5277
  this.compressionThreshold = 24 * 1000;
5278
5278
  this.bc = null;
@@ -7673,11 +7673,6 @@ function Timing (app, opts) {
7673
7673
  if (shouldSkip) {
7674
7674
  return;
7675
7675
  }
7676
- const failed = entry.responseEnd === 0
7677
- || (entry.transferSize === 0 && entry.decodedBodySize === 0);
7678
- if (failed) {
7679
- app.send(ResourceTiming(entry.startTime + getTimeOrigin(), 0, 0, 0, 0, 0, entry.name, entry.initiatorType, 0, true));
7680
- }
7681
7676
  app.send(ResourceTiming(entry.startTime + getTimeOrigin(), entry.duration, entry.responseStart && entry.startTime ? entry.responseStart - entry.startTime : 0, entry.transferSize > entry.encodedBodySize ? entry.transferSize - entry.encodedBodySize : 0, entry.encodedBodySize || 0, entry.decodedBodySize || 0, app.sanitizer.privateMode ? entry.name.replaceAll(/./g, '*') : entry.name, entry.initiatorType, entry.transferSize,
7682
7677
  // @ts-ignore
7683
7678
  (entry.responseStatus && entry.responseStatus === 304) || entry.transferSize === 0));
@@ -7688,14 +7683,8 @@ function Timing (app, opts) {
7688
7683
  return app.send(WebVitals(msg.name, String(msg.value)));
7689
7684
  }
7690
7685
  }
7691
- let prevSessionID;
7692
7686
  app.attachStartCallback(function ({ sessionID }) {
7693
- if (sessionID !== prevSessionID) {
7694
- // Send past page resources on a newly started session
7695
- performance.getEntriesByType('resource').forEach(resourceTiming);
7696
- prevSessionID = sessionID;
7697
- }
7698
- observer.observe({ entryTypes: ['resource'] });
7687
+ observer.observe({ type: 'resource', buffered: true });
7699
7688
  // browser support:
7700
7689
  // onCLS(): Chromium
7701
7690
  // onFCP(): Chromium, Firefox, Safari
@@ -7859,15 +7848,17 @@ function Scroll (app, insideIframe) {
7859
7848
  }, 5, false);
7860
7849
  }
7861
7850
 
7862
- function Viewport (app) {
7851
+ function Viewport (app, options) {
7863
7852
  let url, width, height;
7864
7853
  let navigationStart;
7865
7854
  let referrer = document.referrer;
7855
+ const urlSanitizer = options?.urlSanitizer || ((u) => u);
7856
+ const titleSanitizer = options?.titleSanitizer || ((t) => t);
7866
7857
  const sendSetPageLocation = app.safe(() => {
7867
7858
  const { URL } = document;
7868
7859
  if (URL !== url) {
7869
- url = URL;
7870
- const safeTitle = app.sanitizer.privateMode ? stringWiper(document.title) : document.title;
7860
+ url = urlSanitizer(URL);
7861
+ const safeTitle = app.sanitizer.privateMode ? stringWiper(document.title) : titleSanitizer(document.title);
7871
7862
  const safeUrl = app.sanitizer.privateMode ? stringWiper(url) : url;
7872
7863
  const safeReferrer = app.sanitizer.privateMode ? stringWiper(referrer) : referrer;
7873
7864
  app.send(SetPageLocation(safeUrl, safeReferrer, navigationStart, safeTitle));
@@ -9255,10 +9246,17 @@ class XHRProxy {
9255
9246
  }
9256
9247
  }
9257
9248
 
9258
- const getWarning = (api) => {
9249
+ const warn = (api) => {
9259
9250
  const str = `Openreplay: Can't find ${api} in global context.`;
9260
9251
  console.warn(str);
9261
9252
  };
9253
+ const OR_FLAG = Symbol('OpenReplayProxyOriginal');
9254
+ const isProxied = (fn) => !!fn && fn[OR_FLAG] !== undefined;
9255
+ const unwrap = (fn) => isProxied(fn) ? fn[OR_FLAG] : fn;
9256
+ const wrap = (proxy, orig) => {
9257
+ proxy[OR_FLAG] = orig;
9258
+ return proxy;
9259
+ };
9262
9260
  /**
9263
9261
  * Creates network proxies for XMLHttpRequest, fetch, and sendBeacon to intercept and monitor network requests and
9264
9262
  * responses.
@@ -9292,26 +9290,24 @@ function createNetworkProxy(context, ignoredHeaders, setSessionTokenHeader, sani
9292
9290
  if (!context)
9293
9291
  return;
9294
9292
  if (modules.xhr) {
9295
- if (context.XMLHttpRequest) {
9296
- context.XMLHttpRequest = XHRProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher);
9297
- }
9293
+ const original = unwrap(context.XMLHttpRequest);
9294
+ if (!original)
9295
+ warn('XMLHttpRequest');
9298
9296
  else {
9299
- getWarning("XMLHttpRequest");
9297
+ context.XMLHttpRequest = wrap(XHRProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher), original);
9300
9298
  }
9301
9299
  }
9302
9300
  if (modules.fetch) {
9303
- if (context.fetch) {
9304
- context.fetch = FetchProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher);
9305
- }
9301
+ const original = unwrap(context.fetch);
9302
+ if (!original)
9303
+ warn('fetch');
9306
9304
  else {
9307
- getWarning("fetch");
9305
+ context.fetch = wrap(FetchProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher), original);
9308
9306
  }
9309
9307
  }
9310
- if (modules.beacon) {
9311
- if ((_a = context.navigator) === null || _a === void 0 ? void 0 : _a.sendBeacon) {
9312
- const origBeacon = context.navigator.sendBeacon;
9313
- context.navigator.sendBeacon = BeaconProxy.create(origBeacon, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl);
9314
- }
9308
+ if (modules.beacon && ((_a = context.navigator) === null || _a === void 0 ? void 0 : _a.sendBeacon)) {
9309
+ const original = unwrap(context.navigator.sendBeacon);
9310
+ context.navigator.sendBeacon = wrap(BeaconProxy.create(original, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl), original);
9315
9311
  }
9316
9312
  }
9317
9313
 
@@ -9652,7 +9648,7 @@ class API {
9652
9648
  this.signalStartIssue = (reason, missingApi) => {
9653
9649
  const doNotTrack = this.checkDoNotTrack();
9654
9650
  console.log("Tracker couldn't start due to:", JSON.stringify({
9655
- trackerVersion: '16.4.3',
9651
+ trackerVersion: '16.4.4',
9656
9652
  projectKey: this.options.projectKey,
9657
9653
  doNotTrack,
9658
9654
  reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
@@ -9740,7 +9736,7 @@ class API {
9740
9736
  this.app = app;
9741
9737
  if (!this.crossdomainMode) {
9742
9738
  // no need to send iframe viewport data since its a node for us
9743
- Viewport(app);
9739
+ Viewport(app, options.urls);
9744
9740
  // calculated in main window
9745
9741
  Connection(app);
9746
9742
  // while we can calculate it here, trying to compute it for all parts is hard