@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.
- package/cjs/app/index.d.ts +6 -1
- package/cjs/app/index.js +22 -3
- package/cjs/app/observer/observer.js +2 -2
- package/cjs/app/session.d.ts +10 -0
- package/cjs/app/session.js +3 -0
- package/cjs/index.d.ts +11 -0
- package/cjs/index.js +28 -1
- package/cjs/modules/Network/fetchProxy.d.ts +34 -0
- package/cjs/modules/Network/fetchProxy.js +240 -0
- package/cjs/modules/Network/index.d.ts +3 -0
- package/cjs/modules/Network/index.js +9 -0
- package/cjs/modules/Network/networkMessage.d.ts +49 -0
- package/cjs/modules/Network/networkMessage.js +82 -0
- package/cjs/modules/Network/types.d.ts +13 -0
- package/cjs/modules/Network/types.js +3 -0
- package/cjs/modules/Network/utils.d.ts +11 -0
- package/cjs/modules/Network/utils.js +213 -0
- package/cjs/modules/Network/xhrProxy.d.ts +47 -0
- package/cjs/modules/Network/xhrProxy.js +209 -0
- package/cjs/modules/attributeSender.d.ts +14 -0
- package/cjs/modules/attributeSender.js +44 -0
- package/cjs/modules/console.js +21 -13
- package/cjs/modules/featureFlags.d.ts +25 -0
- package/cjs/modules/featureFlags.js +100 -0
- package/cjs/modules/img.js +4 -4
- package/cjs/modules/network.d.ts +3 -4
- package/cjs/modules/network.js +13 -3
- package/coverage/clover.xml +1412 -900
- package/coverage/coverage-final.json +22 -16
- package/coverage/lcov-report/index.html +58 -43
- package/coverage/lcov-report/main/app/guards.ts.html +42 -42
- package/coverage/lcov-report/main/app/index.html +46 -46
- package/coverage/lcov-report/main/app/index.ts.html +104 -8
- package/coverage/lcov-report/main/app/logger.ts.html +1 -1
- package/coverage/lcov-report/main/app/messages.gen.ts.html +146 -146
- package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/index.html +1 -1
- package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/top_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/sanitizer.ts.html +98 -98
- package/coverage/lcov-report/main/app/session.ts.html +47 -5
- package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
- package/coverage/lcov-report/main/index.html +24 -24
- package/coverage/lcov-report/main/index.ts.html +138 -6
- package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +949 -0
- package/coverage/lcov-report/main/{vendors/finder → modules/Network}/index.html +72 -12
- package/coverage/lcov-report/main/modules/Network/index.ts.html +169 -0
- package/coverage/lcov-report/main/{app/nodes.ts.html → modules/Network/networkMessage.ts.html} +130 -115
- package/coverage/lcov-report/main/modules/Network/utils.ts.html +700 -0
- package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +823 -0
- package/coverage/lcov-report/main/modules/attributeSender.ts.html +217 -0
- package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/console.ts.html +174 -147
- package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +1 -1
- package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
- package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
- package/coverage/lcov-report/main/modules/featureFlags.ts.html +415 -0
- package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
- package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
- package/coverage/lcov-report/main/modules/img.ts.html +6 -6
- package/coverage/lcov-report/main/modules/index.html +54 -24
- package/coverage/lcov-report/main/modules/input.ts.html +1 -1
- package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
- package/coverage/lcov-report/main/modules/network.ts.html +70 -70
- package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
- package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
- package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
- package/coverage/lcov-report/main/modules/timing.ts.html +1 -1
- package/coverage/lcov-report/main/modules/viewport.ts.html +1 -1
- package/coverage/lcov-report/main/utils.ts.html +97 -97
- package/coverage/lcov-report/webworker/BatchWriter.ts.html +125 -176
- package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +88 -88
- package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +110 -110
- package/coverage/lcov-report/webworker/QueueSender.ts.html +140 -110
- package/coverage/lcov-report/webworker/index.html +56 -71
- package/coverage/lcov-report/webworker/index.ts.html +34 -10
- package/coverage/lcov.info +2524 -1552
- package/lib/app/index.d.ts +6 -1
- package/lib/app/index.js +22 -3
- package/lib/app/observer/observer.js +3 -3
- package/lib/app/session.d.ts +10 -0
- package/lib/app/session.js +3 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +28 -1
- package/lib/modules/Network/fetchProxy.d.ts +34 -0
- package/lib/modules/Network/fetchProxy.js +234 -0
- package/lib/modules/Network/index.d.ts +3 -0
- package/lib/modules/Network/index.js +6 -0
- package/lib/modules/Network/networkMessage.d.ts +49 -0
- package/lib/modules/Network/networkMessage.js +78 -0
- package/lib/modules/Network/types.d.ts +13 -0
- package/lib/modules/Network/types.js +2 -0
- package/lib/modules/Network/utils.d.ts +11 -0
- package/lib/modules/Network/utils.js +201 -0
- package/lib/modules/Network/xhrProxy.d.ts +47 -0
- package/lib/modules/Network/xhrProxy.js +204 -0
- package/lib/modules/attributeSender.d.ts +14 -0
- package/lib/modules/attributeSender.js +39 -0
- package/lib/modules/console.js +21 -13
- package/lib/modules/featureFlags.d.ts +25 -0
- package/lib/modules/featureFlags.js +97 -0
- package/lib/modules/img.js +5 -5
- package/lib/modules/network.d.ts +3 -4
- package/lib/modules/network.js +13 -3
- package/package.json +3 -2
- package/coverage/lcov-report/main/app/observer/observer.ts.html +0 -1282
- package/coverage/lcov-report/main/vendors/finder/finder.ts.html +0 -1381
- package/coverage/lcov-report/webworker/StringDictionary.ts.html +0 -124
|
@@ -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,97 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
export default class FeatureFlags {
|
|
11
|
+
constructor(app) {
|
|
12
|
+
this.app = app;
|
|
13
|
+
this.storageKey = '__openreplay_flags';
|
|
14
|
+
const persistFlags = this.app.sessionStorage.getItem(this.storageKey);
|
|
15
|
+
if (persistFlags) {
|
|
16
|
+
const persistFlagsStrArr = persistFlags.split(';').filter(Boolean);
|
|
17
|
+
this.flags = persistFlagsStrArr.map((flag) => JSON.parse(flag));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
getFeatureFlag(flagName) {
|
|
21
|
+
return this.flags.find((flag) => flag.key === flagName);
|
|
22
|
+
}
|
|
23
|
+
isFlagEnabled(flagName) {
|
|
24
|
+
return this.flags.findIndex((flag) => flag.key === flagName) !== -1;
|
|
25
|
+
}
|
|
26
|
+
onFlagsLoad(cb) {
|
|
27
|
+
this.onFlagsCb = cb;
|
|
28
|
+
}
|
|
29
|
+
reloadFlags() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const persistFlagsStr = this.app.sessionStorage.getItem(this.storageKey);
|
|
32
|
+
const persistFlags = {};
|
|
33
|
+
if (persistFlagsStr) {
|
|
34
|
+
const persistArray = persistFlagsStr.split(';').filter(Boolean);
|
|
35
|
+
persistArray.forEach((flag) => {
|
|
36
|
+
const flagObj = JSON.parse(flag);
|
|
37
|
+
persistFlags[flagObj.key] = { key: flagObj.key, value: flagObj.value };
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const sessionInfo = this.app.session.getInfo();
|
|
41
|
+
const userInfo = this.app.session.userInfo;
|
|
42
|
+
const requestObject = {
|
|
43
|
+
projectID: sessionInfo.projectID,
|
|
44
|
+
userID: sessionInfo.userID,
|
|
45
|
+
metadata: sessionInfo.metadata,
|
|
46
|
+
referrer: document.referrer,
|
|
47
|
+
// todo: get from backend
|
|
48
|
+
os: userInfo.userOS,
|
|
49
|
+
device: userInfo.userDevice,
|
|
50
|
+
country: userInfo.userCountry,
|
|
51
|
+
state: userInfo.userState,
|
|
52
|
+
city: userInfo.userCity,
|
|
53
|
+
browser: userInfo.userBrowser,
|
|
54
|
+
persistFlags: persistFlags,
|
|
55
|
+
};
|
|
56
|
+
const resp = yield fetch(this.app.options.ingestPoint + '/v1/web/feature-flags', {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: {
|
|
59
|
+
'Content-Type': 'application/json',
|
|
60
|
+
Authorization: `Bearer ${this.app.session.getSessionToken()}`,
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify(requestObject),
|
|
63
|
+
});
|
|
64
|
+
if (resp.status === 200) {
|
|
65
|
+
const data = yield resp.json();
|
|
66
|
+
return this.handleFlags(data.flags);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
handleFlags(flags) {
|
|
71
|
+
var _a;
|
|
72
|
+
const persistFlags = [];
|
|
73
|
+
flags.forEach((flag) => {
|
|
74
|
+
if (flag.is_persist)
|
|
75
|
+
persistFlags.push(flag);
|
|
76
|
+
});
|
|
77
|
+
let str = '';
|
|
78
|
+
const uniquePersistFlags = this.diffPersist(persistFlags);
|
|
79
|
+
uniquePersistFlags.forEach((flag) => {
|
|
80
|
+
str += `${JSON.stringify(flag)};`;
|
|
81
|
+
});
|
|
82
|
+
this.app.sessionStorage.setItem(this.storageKey, str);
|
|
83
|
+
this.flags = flags;
|
|
84
|
+
return (_a = this.onFlagsCb) === null || _a === void 0 ? void 0 : _a.call(this, flags);
|
|
85
|
+
}
|
|
86
|
+
clearPersistFlags() {
|
|
87
|
+
this.app.sessionStorage.removeItem(this.storageKey);
|
|
88
|
+
}
|
|
89
|
+
diffPersist(flags) {
|
|
90
|
+
const persistFlags = this.app.sessionStorage.getItem(this.storageKey);
|
|
91
|
+
if (!persistFlags)
|
|
92
|
+
return flags;
|
|
93
|
+
const persistFlagsStrArr = persistFlags.split(';').filter(Boolean);
|
|
94
|
+
const persistFlagsArr = persistFlagsStrArr.map((flag) => JSON.parse(flag));
|
|
95
|
+
return flags.filter((flag) => persistFlagsArr.findIndex((pf) => pf.key === flag.key) === -1);
|
|
96
|
+
}
|
|
97
|
+
}
|
package/lib/modules/img.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isURL, IS_FIREFOX, MAX_STR_LEN } from '../utils.js';
|
|
2
|
-
import { ResourceTiming, SetNodeAttributeURLBased
|
|
2
|
+
import { ResourceTiming, SetNodeAttributeURLBased } from '../app/messages.gen.js';
|
|
3
3
|
import { hasTag } from '../app/guards.js';
|
|
4
4
|
function resolveURL(url, location = document.location) {
|
|
5
5
|
url = url.trim();
|
|
@@ -24,13 +24,13 @@ function isSVGInFireFox(url) {
|
|
|
24
24
|
const PLACEHOLDER_SRC = 'https://static.openreplay.com/tracker/placeholder.jpeg';
|
|
25
25
|
export default function (app) {
|
|
26
26
|
function sendPlaceholder(id, node) {
|
|
27
|
-
app.
|
|
27
|
+
app.attributeSender.sendSetAttribute(id, 'src', PLACEHOLDER_SRC);
|
|
28
28
|
const { width, height } = node.getBoundingClientRect();
|
|
29
29
|
if (!node.hasAttribute('width')) {
|
|
30
|
-
app.
|
|
30
|
+
app.attributeSender.sendSetAttribute(id, 'width', String(width));
|
|
31
31
|
}
|
|
32
32
|
if (!node.hasAttribute('height')) {
|
|
33
|
-
app.
|
|
33
|
+
app.attributeSender.sendSetAttribute(id, 'height', String(height));
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
const sendSrcset = function (id, img) {
|
|
@@ -42,7 +42,7 @@ export default function (app) {
|
|
|
42
42
|
.split(',')
|
|
43
43
|
.map((str) => resolveURL(str))
|
|
44
44
|
.join(',');
|
|
45
|
-
app.
|
|
45
|
+
app.attributeSender.sendSetAttribute(id, 'srcset', resolvedSrcset);
|
|
46
46
|
};
|
|
47
47
|
const sendSrc = function (id, img) {
|
|
48
48
|
if (img.src.length > MAX_STR_LEN) {
|
package/lib/modules/network.d.ts
CHANGED
|
@@ -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:
|
|
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
|
|
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 {};
|
package/lib/modules/network.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NetworkRequest } from '../app/messages.gen.js';
|
|
2
2
|
import { getTimeOrigin } from '../utils.js';
|
|
3
3
|
import axiosSpy from './axiosSpy.js';
|
|
4
|
+
import setProxy from './Network/index.js';
|
|
4
5
|
function getXHRRequestDataObject(xhr) {
|
|
5
6
|
// @ts-ignore this is 3x faster than using Map<XHR, XHRRequestData>
|
|
6
7
|
if (!xhr.__or_req_data__) {
|
|
@@ -21,6 +22,7 @@ export default function (app, opts = {}) {
|
|
|
21
22
|
sessionTokenHeader: false,
|
|
22
23
|
captureInIframes: true,
|
|
23
24
|
axiosInstances: undefined,
|
|
25
|
+
useProxy: true,
|
|
24
26
|
}, opts);
|
|
25
27
|
const ignoreHeaders = options.ignoreHeaders;
|
|
26
28
|
const isHIgnored = Array.isArray(ignoreHeaders)
|
|
@@ -37,13 +39,14 @@ export default function (app, opts = {}) {
|
|
|
37
39
|
}
|
|
38
40
|
function sanitize(reqResInfo) {
|
|
39
41
|
if (!options.capturePayload) {
|
|
42
|
+
// @ts-ignore
|
|
40
43
|
delete reqResInfo.request.body;
|
|
41
44
|
delete reqResInfo.response.body;
|
|
42
45
|
}
|
|
43
46
|
if (options.sanitizer) {
|
|
44
47
|
const resBody = reqResInfo.response.body;
|
|
45
48
|
if (typeof resBody === 'string') {
|
|
46
|
-
// Parse response in order to have handy view in
|
|
49
|
+
// Parse response in order to have handy view in sanitization function
|
|
47
50
|
try {
|
|
48
51
|
reqResInfo.response.body = JSON.parse(resBody);
|
|
49
52
|
}
|
|
@@ -66,6 +69,10 @@ export default function (app, opts = {}) {
|
|
|
66
69
|
return JSON.stringify(r);
|
|
67
70
|
}
|
|
68
71
|
const patchWindow = (context) => {
|
|
72
|
+
/* ====== modern way ====== */
|
|
73
|
+
if (options.useProxy) {
|
|
74
|
+
return setProxy(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => app.send(message), (url) => app.isServiceURL(url));
|
|
75
|
+
}
|
|
69
76
|
/* ====== Fetch ====== */
|
|
70
77
|
const origFetch = context.fetch.bind(context);
|
|
71
78
|
const trackFetch = (input, init = {}) => {
|
|
@@ -126,7 +133,8 @@ export default function (app, opts = {}) {
|
|
|
126
133
|
status: r.status,
|
|
127
134
|
request: {
|
|
128
135
|
headers: reqHs,
|
|
129
|
-
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
body: init.body || null,
|
|
130
138
|
},
|
|
131
139
|
response: {
|
|
132
140
|
headers: resHs,
|
|
@@ -136,6 +144,7 @@ export default function (app, opts = {}) {
|
|
|
136
144
|
if (!reqResInfo) {
|
|
137
145
|
return;
|
|
138
146
|
}
|
|
147
|
+
console.log('original', NetworkRequest('fetch', method, String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), r.status, startTime + getTimeOrigin(), duration));
|
|
139
148
|
app.send(NetworkRequest('fetch', method, String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), r.status, startTime + getTimeOrigin(), duration));
|
|
140
149
|
})
|
|
141
150
|
.catch((e) => app.debug.error('Could not process Fetch response:', e));
|
|
@@ -175,7 +184,8 @@ export default function (app, opts = {}) {
|
|
|
175
184
|
status: xhr.status,
|
|
176
185
|
request: {
|
|
177
186
|
headers: reqHs,
|
|
178
|
-
|
|
187
|
+
// @ts-ignore
|
|
188
|
+
body: reqBody || null,
|
|
179
189
|
},
|
|
180
190
|
response: {
|
|
181
191
|
headers: headerMap,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openreplay/tracker",
|
|
3
3
|
"description": "The OpenReplay tracker main package",
|
|
4
|
-
"version": "8.0.
|
|
4
|
+
"version": "8.0.1-beta14",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"logging",
|
|
7
7
|
"replay"
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"lint-front": "lint-staged",
|
|
25
25
|
"test": "jest --coverage=false",
|
|
26
26
|
"test:ci": "jest --coverage=true",
|
|
27
|
-
"postversion": "npm run build"
|
|
27
|
+
"postversion": "npm run build",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@babel/core": "^7.10.2",
|