@openreplay/tracker 8.0.0-beta.1 → 8.0.1-beta14

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 (111) hide show
  1. package/cjs/app/index.d.ts +6 -1
  2. package/cjs/app/index.js +22 -3
  3. package/cjs/app/observer/observer.js +2 -2
  4. package/cjs/app/session.d.ts +10 -0
  5. package/cjs/app/session.js +3 -0
  6. package/cjs/index.d.ts +11 -0
  7. package/cjs/index.js +28 -1
  8. package/cjs/modules/Network/fetchProxy.d.ts +34 -0
  9. package/cjs/modules/Network/fetchProxy.js +240 -0
  10. package/cjs/modules/Network/index.d.ts +3 -0
  11. package/cjs/modules/Network/index.js +9 -0
  12. package/cjs/modules/Network/networkMessage.d.ts +49 -0
  13. package/cjs/modules/Network/networkMessage.js +82 -0
  14. package/cjs/modules/Network/types.d.ts +13 -0
  15. package/cjs/modules/Network/types.js +3 -0
  16. package/cjs/modules/Network/utils.d.ts +11 -0
  17. package/cjs/modules/Network/utils.js +213 -0
  18. package/cjs/modules/Network/xhrProxy.d.ts +47 -0
  19. package/cjs/modules/Network/xhrProxy.js +209 -0
  20. package/cjs/modules/attributeSender.d.ts +14 -0
  21. package/cjs/modules/attributeSender.js +44 -0
  22. package/cjs/modules/console.js +21 -13
  23. package/cjs/modules/featureFlags.d.ts +25 -0
  24. package/cjs/modules/featureFlags.js +100 -0
  25. package/cjs/modules/img.js +4 -4
  26. package/cjs/modules/network.d.ts +3 -4
  27. package/cjs/modules/network.js +13 -3
  28. package/coverage/clover.xml +1412 -900
  29. package/coverage/coverage-final.json +22 -16
  30. package/coverage/lcov-report/index.html +58 -43
  31. package/coverage/lcov-report/main/app/guards.ts.html +42 -42
  32. package/coverage/lcov-report/main/app/index.html +46 -46
  33. package/coverage/lcov-report/main/app/index.ts.html +104 -8
  34. package/coverage/lcov-report/main/app/logger.ts.html +1 -1
  35. package/coverage/lcov-report/main/app/messages.gen.ts.html +146 -146
  36. package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
  37. package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
  38. package/coverage/lcov-report/main/app/observer/index.html +1 -1
  39. package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
  40. package/coverage/lcov-report/main/app/observer/top_observer.ts.html +1 -1
  41. package/coverage/lcov-report/main/app/sanitizer.ts.html +98 -98
  42. package/coverage/lcov-report/main/app/session.ts.html +47 -5
  43. package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
  44. package/coverage/lcov-report/main/index.html +24 -24
  45. package/coverage/lcov-report/main/index.ts.html +138 -6
  46. package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +949 -0
  47. package/coverage/lcov-report/main/{vendors/finder → modules/Network}/index.html +72 -12
  48. package/coverage/lcov-report/main/modules/Network/index.ts.html +169 -0
  49. package/coverage/lcov-report/main/{app/nodes.ts.html → modules/Network/networkMessage.ts.html} +130 -115
  50. package/coverage/lcov-report/main/modules/Network/utils.ts.html +700 -0
  51. package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +823 -0
  52. package/coverage/lcov-report/main/modules/attributeSender.ts.html +217 -0
  53. package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
  54. package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
  55. package/coverage/lcov-report/main/modules/console.ts.html +174 -147
  56. package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +1 -1
  57. package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
  58. package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
  59. package/coverage/lcov-report/main/modules/featureFlags.ts.html +415 -0
  60. package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
  61. package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
  62. package/coverage/lcov-report/main/modules/img.ts.html +6 -6
  63. package/coverage/lcov-report/main/modules/index.html +54 -24
  64. package/coverage/lcov-report/main/modules/input.ts.html +1 -1
  65. package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
  66. package/coverage/lcov-report/main/modules/network.ts.html +70 -70
  67. package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
  68. package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
  69. package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
  70. package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
  71. package/coverage/lcov-report/main/modules/timing.ts.html +1 -1
  72. package/coverage/lcov-report/main/modules/viewport.ts.html +1 -1
  73. package/coverage/lcov-report/main/utils.ts.html +97 -97
  74. package/coverage/lcov-report/webworker/BatchWriter.ts.html +125 -176
  75. package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +88 -88
  76. package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +110 -110
  77. package/coverage/lcov-report/webworker/QueueSender.ts.html +140 -110
  78. package/coverage/lcov-report/webworker/index.html +56 -71
  79. package/coverage/lcov-report/webworker/index.ts.html +34 -10
  80. package/coverage/lcov.info +2524 -1552
  81. package/lib/app/index.d.ts +6 -1
  82. package/lib/app/index.js +22 -3
  83. package/lib/app/observer/observer.js +3 -3
  84. package/lib/app/session.d.ts +10 -0
  85. package/lib/app/session.js +3 -0
  86. package/lib/index.d.ts +11 -0
  87. package/lib/index.js +28 -1
  88. package/lib/modules/Network/fetchProxy.d.ts +34 -0
  89. package/lib/modules/Network/fetchProxy.js +234 -0
  90. package/lib/modules/Network/index.d.ts +3 -0
  91. package/lib/modules/Network/index.js +6 -0
  92. package/lib/modules/Network/networkMessage.d.ts +49 -0
  93. package/lib/modules/Network/networkMessage.js +78 -0
  94. package/lib/modules/Network/types.d.ts +13 -0
  95. package/lib/modules/Network/types.js +2 -0
  96. package/lib/modules/Network/utils.d.ts +11 -0
  97. package/lib/modules/Network/utils.js +201 -0
  98. package/lib/modules/Network/xhrProxy.d.ts +47 -0
  99. package/lib/modules/Network/xhrProxy.js +204 -0
  100. package/lib/modules/attributeSender.d.ts +14 -0
  101. package/lib/modules/attributeSender.js +39 -0
  102. package/lib/modules/console.js +21 -13
  103. package/lib/modules/featureFlags.d.ts +25 -0
  104. package/lib/modules/featureFlags.js +97 -0
  105. package/lib/modules/img.js +5 -5
  106. package/lib/modules/network.d.ts +3 -4
  107. package/lib/modules/network.js +13 -3
  108. package/package.json +3 -2
  109. package/coverage/lcov-report/main/app/observer/observer.ts.html +0 -1282
  110. package/coverage/lcov-report/main/vendors/finder/finder.ts.html +0 -1381
  111. package/coverage/lcov-report/webworker/StringDictionary.ts.html +0 -124
@@ -92,26 +92,34 @@ function default_1(app, opts) {
92
92
  return;
93
93
  }
94
94
  const sendConsoleLog = app.safe((level, args) => app.send((0, messages_gen_js_1.ConsoleLog)(level, printf(args))));
95
- let n;
95
+ let n = 0;
96
96
  const reset = () => {
97
97
  n = 0;
98
98
  };
99
99
  app.attachStartCallback(reset);
100
100
  app.ticker.attach(reset, 33, false);
101
- const patchConsole = (console) => options.consoleMethods.forEach((method) => {
102
- if (consoleMethods.indexOf(method) === -1) {
103
- app.debug.error(`OpenReplay: unsupported console method "${method}"`);
104
- return;
105
- }
106
- const fn = console[method];
107
- console[method] = function (...args) {
108
- fn.apply(this, args);
109
- if (n++ > options.consoleThrottling) {
101
+ const patchConsole = (console) => {
102
+ const handler = {
103
+ apply: function (target, thisArg, argumentsList) {
104
+ target.apply(console, argumentsList);
105
+ n = n + 1;
106
+ if (n > options.consoleThrottling) {
107
+ return;
108
+ }
109
+ else {
110
+ sendConsoleLog(target.name, argumentsList);
111
+ }
112
+ },
113
+ };
114
+ options.consoleMethods.forEach((method) => {
115
+ if (consoleMethods.indexOf(method) === -1) {
116
+ app.debug.error(`OpenReplay: unsupported console method "${method}"`);
110
117
  return;
111
118
  }
112
- sendConsoleLog(method, args);
113
- };
114
- });
119
+ const fn = console[method];
120
+ console[method] = new Proxy(fn, handler);
121
+ });
122
+ };
115
123
  const patchContext = app.safe((context) => patchConsole(context.console));
116
124
  patchContext(window);
117
125
  app.observer.attachContextCallback(patchContext);
@@ -0,0 +1,25 @@
1
+ import App from '../app/index.js';
2
+ export interface IFeatureFlag {
3
+ key: string;
4
+ is_persist: boolean;
5
+ value: string | boolean;
6
+ payload: string;
7
+ }
8
+ export interface FetchPersistFlagsData {
9
+ key: string;
10
+ value: string | boolean;
11
+ }
12
+ export default class FeatureFlags {
13
+ private readonly app;
14
+ flags: IFeatureFlag[];
15
+ storageKey: string;
16
+ onFlagsCb: (flags: IFeatureFlag[]) => void;
17
+ constructor(app: App);
18
+ getFeatureFlag(flagName: string): IFeatureFlag | undefined;
19
+ isFlagEnabled(flagName: string): boolean;
20
+ onFlagsLoad(cb: (flags: IFeatureFlag[]) => void): void;
21
+ reloadFlags(): Promise<void>;
22
+ handleFlags(flags: IFeatureFlag[]): void;
23
+ clearPersistFlags(): void;
24
+ diffPersist(flags: IFeatureFlag[]): IFeatureFlag[];
25
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ class FeatureFlags {
13
+ constructor(app) {
14
+ this.app = app;
15
+ this.storageKey = '__openreplay_flags';
16
+ const persistFlags = this.app.sessionStorage.getItem(this.storageKey);
17
+ if (persistFlags) {
18
+ const persistFlagsStrArr = persistFlags.split(';').filter(Boolean);
19
+ this.flags = persistFlagsStrArr.map((flag) => JSON.parse(flag));
20
+ }
21
+ }
22
+ getFeatureFlag(flagName) {
23
+ return this.flags.find((flag) => flag.key === flagName);
24
+ }
25
+ isFlagEnabled(flagName) {
26
+ return this.flags.findIndex((flag) => flag.key === flagName) !== -1;
27
+ }
28
+ onFlagsLoad(cb) {
29
+ this.onFlagsCb = cb;
30
+ }
31
+ reloadFlags() {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ const persistFlagsStr = this.app.sessionStorage.getItem(this.storageKey);
34
+ const persistFlags = {};
35
+ if (persistFlagsStr) {
36
+ const persistArray = persistFlagsStr.split(';').filter(Boolean);
37
+ persistArray.forEach((flag) => {
38
+ const flagObj = JSON.parse(flag);
39
+ persistFlags[flagObj.key] = { key: flagObj.key, value: flagObj.value };
40
+ });
41
+ }
42
+ const sessionInfo = this.app.session.getInfo();
43
+ const userInfo = this.app.session.userInfo;
44
+ const requestObject = {
45
+ projectID: sessionInfo.projectID,
46
+ userID: sessionInfo.userID,
47
+ metadata: sessionInfo.metadata,
48
+ referrer: document.referrer,
49
+ // todo: get from backend
50
+ os: userInfo.userOS,
51
+ device: userInfo.userDevice,
52
+ country: userInfo.userCountry,
53
+ state: userInfo.userState,
54
+ city: userInfo.userCity,
55
+ browser: userInfo.userBrowser,
56
+ persistFlags: persistFlags,
57
+ };
58
+ const resp = yield fetch(this.app.options.ingestPoint + '/v1/web/feature-flags', {
59
+ method: 'POST',
60
+ headers: {
61
+ 'Content-Type': 'application/json',
62
+ Authorization: `Bearer ${this.app.session.getSessionToken()}`,
63
+ },
64
+ body: JSON.stringify(requestObject),
65
+ });
66
+ if (resp.status === 200) {
67
+ const data = yield resp.json();
68
+ return this.handleFlags(data.flags);
69
+ }
70
+ });
71
+ }
72
+ handleFlags(flags) {
73
+ var _a;
74
+ const persistFlags = [];
75
+ flags.forEach((flag) => {
76
+ if (flag.is_persist)
77
+ persistFlags.push(flag);
78
+ });
79
+ let str = '';
80
+ const uniquePersistFlags = this.diffPersist(persistFlags);
81
+ uniquePersistFlags.forEach((flag) => {
82
+ str += `${JSON.stringify(flag)};`;
83
+ });
84
+ this.app.sessionStorage.setItem(this.storageKey, str);
85
+ this.flags = flags;
86
+ return (_a = this.onFlagsCb) === null || _a === void 0 ? void 0 : _a.call(this, flags);
87
+ }
88
+ clearPersistFlags() {
89
+ this.app.sessionStorage.removeItem(this.storageKey);
90
+ }
91
+ diffPersist(flags) {
92
+ const persistFlags = this.app.sessionStorage.getItem(this.storageKey);
93
+ if (!persistFlags)
94
+ return flags;
95
+ const persistFlagsStrArr = persistFlags.split(';').filter(Boolean);
96
+ const persistFlagsArr = persistFlagsStrArr.map((flag) => JSON.parse(flag));
97
+ return flags.filter((flag) => persistFlagsArr.findIndex((pf) => pf.key === flag.key) === -1);
98
+ }
99
+ }
100
+ exports.default = FeatureFlags;
@@ -26,13 +26,13 @@ function isSVGInFireFox(url) {
26
26
  const PLACEHOLDER_SRC = 'https://static.openreplay.com/tracker/placeholder.jpeg';
27
27
  function default_1(app) {
28
28
  function sendPlaceholder(id, node) {
29
- app.send((0, messages_gen_js_1.SetNodeAttribute)(id, 'src', PLACEHOLDER_SRC));
29
+ app.attributeSender.sendSetAttribute(id, 'src', PLACEHOLDER_SRC);
30
30
  const { width, height } = node.getBoundingClientRect();
31
31
  if (!node.hasAttribute('width')) {
32
- app.send((0, messages_gen_js_1.SetNodeAttribute)(id, 'width', String(width)));
32
+ app.attributeSender.sendSetAttribute(id, 'width', String(width));
33
33
  }
34
34
  if (!node.hasAttribute('height')) {
35
- app.send((0, messages_gen_js_1.SetNodeAttribute)(id, 'height', String(height)));
35
+ app.attributeSender.sendSetAttribute(id, 'height', String(height));
36
36
  }
37
37
  }
38
38
  const sendSrcset = function (id, img) {
@@ -44,7 +44,7 @@ function default_1(app) {
44
44
  .split(',')
45
45
  .map((str) => resolveURL(str))
46
46
  .join(',');
47
- app.send((0, messages_gen_js_1.SetNodeAttribute)(id, 'srcset', resolvedSrcset));
47
+ app.attributeSender.sendSetAttribute(id, 'srcset', resolvedSrcset);
48
48
  };
49
49
  const sendSrc = function (id, img) {
50
50
  if (img.src.length > utils_js_1.MAX_STR_LEN) {
@@ -1,9 +1,7 @@
1
1
  import type App from '../app/index.js';
2
2
  import type { AxiosInstance } from './axiosSpy.js';
3
- type XHRRequestBody = Parameters<XMLHttpRequest['send']>[0];
4
- type FetchRequestBody = RequestInit['body'];
5
3
  interface RequestData {
6
- body: XHRRequestBody | FetchRequestBody;
4
+ body: string | null;
7
5
  headers: Record<string, string>;
8
6
  }
9
7
  interface ResponseData {
@@ -17,7 +15,7 @@ export interface RequestResponseData {
17
15
  request: RequestData;
18
16
  response: ResponseData;
19
17
  }
20
- type Sanitizer = (data: RequestResponseData) => RequestResponseData | null;
18
+ type Sanitizer = (data: RequestResponseData) => RequestResponseData;
21
19
  export interface Options {
22
20
  sessionTokenHeader: string | boolean;
23
21
  failuresOnly: boolean;
@@ -26,6 +24,7 @@ export interface Options {
26
24
  captureInIframes: boolean;
27
25
  sanitizer?: Sanitizer;
28
26
  axiosInstances?: Array<AxiosInstance>;
27
+ useProxy?: boolean;
29
28
  }
30
29
  export default function (app: App, opts?: Partial<Options>): void;
31
30
  export {};
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const messages_gen_js_1 = require("../app/messages.gen.js");
4
4
  const utils_js_1 = require("../utils.js");
5
5
  const axiosSpy_js_1 = require("./axiosSpy.js");
6
+ const index_js_1 = require("./Network/index.js");
6
7
  function getXHRRequestDataObject(xhr) {
7
8
  // @ts-ignore this is 3x faster than using Map<XHR, XHRRequestData>
8
9
  if (!xhr.__or_req_data__) {
@@ -23,6 +24,7 @@ function default_1(app, opts = {}) {
23
24
  sessionTokenHeader: false,
24
25
  captureInIframes: true,
25
26
  axiosInstances: undefined,
27
+ useProxy: true,
26
28
  }, opts);
27
29
  const ignoreHeaders = options.ignoreHeaders;
28
30
  const isHIgnored = Array.isArray(ignoreHeaders)
@@ -39,13 +41,14 @@ function default_1(app, opts = {}) {
39
41
  }
40
42
  function sanitize(reqResInfo) {
41
43
  if (!options.capturePayload) {
44
+ // @ts-ignore
42
45
  delete reqResInfo.request.body;
43
46
  delete reqResInfo.response.body;
44
47
  }
45
48
  if (options.sanitizer) {
46
49
  const resBody = reqResInfo.response.body;
47
50
  if (typeof resBody === 'string') {
48
- // Parse response in order to have handy view in sanitisation function
51
+ // Parse response in order to have handy view in sanitization function
49
52
  try {
50
53
  reqResInfo.response.body = JSON.parse(resBody);
51
54
  }
@@ -68,6 +71,10 @@ function default_1(app, opts = {}) {
68
71
  return JSON.stringify(r);
69
72
  }
70
73
  const patchWindow = (context) => {
74
+ /* ====== modern way ====== */
75
+ if (options.useProxy) {
76
+ return (0, index_js_1.default)(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => app.send(message), (url) => app.isServiceURL(url));
77
+ }
71
78
  /* ====== Fetch ====== */
72
79
  const origFetch = context.fetch.bind(context);
73
80
  const trackFetch = (input, init = {}) => {
@@ -128,7 +135,8 @@ function default_1(app, opts = {}) {
128
135
  status: r.status,
129
136
  request: {
130
137
  headers: reqHs,
131
- body: init.body,
138
+ // @ts-ignore
139
+ body: init.body || null,
132
140
  },
133
141
  response: {
134
142
  headers: resHs,
@@ -138,6 +146,7 @@ function default_1(app, opts = {}) {
138
146
  if (!reqResInfo) {
139
147
  return;
140
148
  }
149
+ console.log('original', (0, messages_gen_js_1.NetworkRequest)('fetch', method, String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), r.status, startTime + (0, utils_js_1.getTimeOrigin)(), duration));
141
150
  app.send((0, messages_gen_js_1.NetworkRequest)('fetch', method, String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), r.status, startTime + (0, utils_js_1.getTimeOrigin)(), duration));
142
151
  })
143
152
  .catch((e) => app.debug.error('Could not process Fetch response:', e));
@@ -177,7 +186,8 @@ function default_1(app, opts = {}) {
177
186
  status: xhr.status,
178
187
  request: {
179
188
  headers: reqHs,
180
- body: reqBody,
189
+ // @ts-ignore
190
+ body: reqBody || null,
181
191
  },
182
192
  response: {
183
193
  headers: headerMap,