@openreplay/tracker 16.3.0-beta.0 → 16.3.0-beta.2
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/dist/cjs/entry.js +49 -162
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +49 -162
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/observer/observer.d.ts +1 -0
- package/dist/cjs/main/modules/cssrules.d.ts +3 -1
- package/dist/cjs/main/utils.d.ts +3 -0
- package/dist/lib/entry.js +49 -162
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +49 -162
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/observer/observer.d.ts +1 -0
- package/dist/lib/main/modules/cssrules.d.ts +3 -1
- package/dist/lib/main/utils.d.ts +3 -0
- package/dist/types/main/app/observer/observer.d.ts +1 -0
- package/dist/types/main/modules/cssrules.d.ts +3 -1
- package/dist/types/main/utils.d.ts +3 -0
- package/package.json +1 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type App from '../app/index.js';
|
|
2
2
|
export interface CssRulesOptions {
|
|
3
|
-
|
|
3
|
+
/** turn this on if you have issues with emotionjs created styles */
|
|
4
4
|
scanInMemoryCSS?: boolean;
|
|
5
|
+
/** how often to scan tracked stylesheets (with "empty" rules) */
|
|
6
|
+
checkCssInterval?: number;
|
|
5
7
|
/**
|
|
6
8
|
Useful for cases where you expect limited amount of mutations
|
|
7
9
|
|
package/dist/cjs/main/utils.d.ts
CHANGED
|
@@ -28,3 +28,6 @@ export declare function createEventListener(target: EventTarget, event: string,
|
|
|
28
28
|
export declare function deleteEventListener(target: EventTarget, event: string, cb: EventListenerOrEventListenerObject, capture?: boolean, forceNgOff?: boolean): void;
|
|
29
29
|
export declare function requestIdleCb(callback: () => void): void;
|
|
30
30
|
export declare function simpleMerge<T>(defaultObj: T, givenObj: Partial<T>): T;
|
|
31
|
+
export declare function throttleWithTrailing<K, Args extends any[]>(fn: (key: K, ...args: Args) => void, interval: number): ((key: K, ...args: Args) => void) & {
|
|
32
|
+
clear: () => void;
|
|
33
|
+
};
|
package/dist/lib/entry.js
CHANGED
|
@@ -1465,6 +1465,43 @@ function simpleMerge(defaultObj, givenObj) {
|
|
|
1465
1465
|
}
|
|
1466
1466
|
return result;
|
|
1467
1467
|
}
|
|
1468
|
+
function throttleWithTrailing(fn, interval) {
|
|
1469
|
+
const lastCalls = new Map();
|
|
1470
|
+
const timeouts = new Map();
|
|
1471
|
+
const lastArgs = new Map();
|
|
1472
|
+
const throttled = function (key, ...args) {
|
|
1473
|
+
const now = Date.now();
|
|
1474
|
+
const lastCall = lastCalls.get(key) ?? 0;
|
|
1475
|
+
const remaining = interval - (now - lastCall);
|
|
1476
|
+
lastArgs.set(key, args);
|
|
1477
|
+
if (remaining <= 0) {
|
|
1478
|
+
if (timeouts.has(key)) {
|
|
1479
|
+
clearTimeout(timeouts.get(key));
|
|
1480
|
+
timeouts.delete(key);
|
|
1481
|
+
}
|
|
1482
|
+
lastCalls.set(key, now);
|
|
1483
|
+
fn(key, ...args);
|
|
1484
|
+
}
|
|
1485
|
+
else if (!timeouts.has(key)) {
|
|
1486
|
+
const timeoutId = setTimeout(() => {
|
|
1487
|
+
lastCalls.set(key, Date.now());
|
|
1488
|
+
timeouts.delete(key);
|
|
1489
|
+
const finalArgs = lastArgs.get(key);
|
|
1490
|
+
fn(key, ...finalArgs);
|
|
1491
|
+
}, remaining);
|
|
1492
|
+
timeouts.set(key, timeoutId);
|
|
1493
|
+
}
|
|
1494
|
+
};
|
|
1495
|
+
throttled.clear = () => {
|
|
1496
|
+
for (const timeout of timeouts.values()) {
|
|
1497
|
+
clearTimeout(timeout);
|
|
1498
|
+
}
|
|
1499
|
+
timeouts.clear();
|
|
1500
|
+
lastArgs.clear();
|
|
1501
|
+
lastCalls.clear();
|
|
1502
|
+
};
|
|
1503
|
+
return throttled;
|
|
1504
|
+
}
|
|
1468
1505
|
|
|
1469
1506
|
// Auto-generated, do not edit
|
|
1470
1507
|
/* eslint-disable */
|
|
@@ -4215,6 +4252,7 @@ class Observer {
|
|
|
4215
4252
|
this.inlineRemoteCss = false;
|
|
4216
4253
|
this.inlinerOptions = undefined;
|
|
4217
4254
|
this.domParser = new DOMParser();
|
|
4255
|
+
this.throttledSetNodeData = throttleWithTrailing((id, parentElement, data) => this.sendNodeData(id, parentElement, data), 30);
|
|
4218
4256
|
this.disableSprites = Boolean(options.disableSprites);
|
|
4219
4257
|
this.inlineRemoteCss = Boolean(options.inlineRemoteCss);
|
|
4220
4258
|
this.inlinerOptions = options.inlinerOptions;
|
|
@@ -4526,7 +4564,7 @@ class Observer {
|
|
|
4526
4564
|
else if (isTextNode(node)) {
|
|
4527
4565
|
// for text node id != 0, hence parentID !== undefined and parent is Element
|
|
4528
4566
|
this.app.send(CreateTextNode(id, parentID, index));
|
|
4529
|
-
this.
|
|
4567
|
+
this.throttledSetNodeData(id, parent, node.data);
|
|
4530
4568
|
}
|
|
4531
4569
|
return true;
|
|
4532
4570
|
}
|
|
@@ -4547,7 +4585,7 @@ class Observer {
|
|
|
4547
4585
|
throw 'commitNode: node is not a text';
|
|
4548
4586
|
}
|
|
4549
4587
|
// for text node id != 0, hence parent is Element
|
|
4550
|
-
this.
|
|
4588
|
+
this.throttledSetNodeData(id, parent, node.data);
|
|
4551
4589
|
}
|
|
4552
4590
|
return true;
|
|
4553
4591
|
}
|
|
@@ -4590,6 +4628,7 @@ class Observer {
|
|
|
4590
4628
|
disconnect() {
|
|
4591
4629
|
this.observer.disconnect();
|
|
4592
4630
|
this.clear();
|
|
4631
|
+
this.throttledSetNodeData.clear();
|
|
4593
4632
|
}
|
|
4594
4633
|
}
|
|
4595
4634
|
|
|
@@ -5202,7 +5241,7 @@ class App {
|
|
|
5202
5241
|
this.stopCallbacks = [];
|
|
5203
5242
|
this.commitCallbacks = [];
|
|
5204
5243
|
this.activityState = ActivityState.NotActive;
|
|
5205
|
-
this.version = '16.3.0-beta.
|
|
5244
|
+
this.version = '16.3.0-beta.2'; // TODO: version compatability check inside each plugin.
|
|
5206
5245
|
this.socketMode = false;
|
|
5207
5246
|
this.compressionThreshold = 24 * 1000;
|
|
5208
5247
|
this.bc = null;
|
|
@@ -8434,152 +8473,6 @@ function isObject(thing) {
|
|
|
8434
8473
|
return thing !== null && typeof thing === 'object';
|
|
8435
8474
|
}
|
|
8436
8475
|
|
|
8437
|
-
const sensitiveParams = new Set([
|
|
8438
|
-
"password",
|
|
8439
|
-
"pass",
|
|
8440
|
-
"pwd",
|
|
8441
|
-
"mdp",
|
|
8442
|
-
"token",
|
|
8443
|
-
"bearer",
|
|
8444
|
-
"jwt",
|
|
8445
|
-
"api_key",
|
|
8446
|
-
"api-key",
|
|
8447
|
-
"apiKey",
|
|
8448
|
-
"secret",
|
|
8449
|
-
"ssn",
|
|
8450
|
-
"zip",
|
|
8451
|
-
"zipcode",
|
|
8452
|
-
"x-api-key",
|
|
8453
|
-
"www-authenticate",
|
|
8454
|
-
"x-csrf-token",
|
|
8455
|
-
"x-requested-with",
|
|
8456
|
-
"x-forwarded-for",
|
|
8457
|
-
"x-real-ip",
|
|
8458
|
-
"cookie",
|
|
8459
|
-
"authorization",
|
|
8460
|
-
"auth",
|
|
8461
|
-
"proxy-authorization",
|
|
8462
|
-
"set-cookie",
|
|
8463
|
-
"account_key",
|
|
8464
|
-
]);
|
|
8465
|
-
function numDigits(x) {
|
|
8466
|
-
return (Math.log10((x ^ (x >> 31)) - (x >> 31)) | 0) + 1;
|
|
8467
|
-
}
|
|
8468
|
-
function obscure(value) {
|
|
8469
|
-
if (typeof value === "number") {
|
|
8470
|
-
const digits = numDigits(value);
|
|
8471
|
-
return "9".repeat(digits);
|
|
8472
|
-
}
|
|
8473
|
-
if (typeof value === "string") {
|
|
8474
|
-
return value.replace(/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\s]/g, '*');
|
|
8475
|
-
}
|
|
8476
|
-
return value;
|
|
8477
|
-
}
|
|
8478
|
-
function filterHeaders(headers) {
|
|
8479
|
-
const filteredHeaders = {};
|
|
8480
|
-
if (Array.isArray(headers)) {
|
|
8481
|
-
headers.forEach(({ name, value }) => {
|
|
8482
|
-
if (sensitiveParams.has(name.toLowerCase())) {
|
|
8483
|
-
filteredHeaders[name] = obscure(value);
|
|
8484
|
-
}
|
|
8485
|
-
else {
|
|
8486
|
-
filteredHeaders[name] = value;
|
|
8487
|
-
}
|
|
8488
|
-
});
|
|
8489
|
-
}
|
|
8490
|
-
else {
|
|
8491
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
8492
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8493
|
-
filteredHeaders[key] = obscure(value);
|
|
8494
|
-
}
|
|
8495
|
-
else {
|
|
8496
|
-
filteredHeaders[key] = value;
|
|
8497
|
-
}
|
|
8498
|
-
}
|
|
8499
|
-
}
|
|
8500
|
-
return filteredHeaders;
|
|
8501
|
-
}
|
|
8502
|
-
function filterBody(body) {
|
|
8503
|
-
if (!body) {
|
|
8504
|
-
return body;
|
|
8505
|
-
}
|
|
8506
|
-
let parsedBody;
|
|
8507
|
-
let isJSON = false;
|
|
8508
|
-
try {
|
|
8509
|
-
parsedBody = JSON.parse(body);
|
|
8510
|
-
isJSON = true;
|
|
8511
|
-
}
|
|
8512
|
-
catch (e) {
|
|
8513
|
-
// not json
|
|
8514
|
-
}
|
|
8515
|
-
if (isJSON) {
|
|
8516
|
-
obscureSensitiveData(parsedBody);
|
|
8517
|
-
return JSON.stringify(parsedBody);
|
|
8518
|
-
}
|
|
8519
|
-
else {
|
|
8520
|
-
const isUrlSearch = typeof body === "string" && body.includes("?") && body.includes("=");
|
|
8521
|
-
if (isUrlSearch) {
|
|
8522
|
-
try {
|
|
8523
|
-
const params = new URLSearchParams(body);
|
|
8524
|
-
for (const key of params.keys()) {
|
|
8525
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8526
|
-
const value = obscure(params.get(key));
|
|
8527
|
-
params.set(key, value);
|
|
8528
|
-
}
|
|
8529
|
-
}
|
|
8530
|
-
return params.toString();
|
|
8531
|
-
}
|
|
8532
|
-
catch (e) {
|
|
8533
|
-
// not url query ?
|
|
8534
|
-
return body;
|
|
8535
|
-
}
|
|
8536
|
-
}
|
|
8537
|
-
else {
|
|
8538
|
-
// not json or url query
|
|
8539
|
-
return body;
|
|
8540
|
-
}
|
|
8541
|
-
}
|
|
8542
|
-
}
|
|
8543
|
-
function sanitizeObject(obj) {
|
|
8544
|
-
obscureSensitiveData(obj);
|
|
8545
|
-
return obj;
|
|
8546
|
-
}
|
|
8547
|
-
function obscureSensitiveData(obj) {
|
|
8548
|
-
if (Array.isArray(obj)) {
|
|
8549
|
-
obj.forEach(obscureSensitiveData);
|
|
8550
|
-
}
|
|
8551
|
-
else if (obj && typeof obj === "object") {
|
|
8552
|
-
for (const key in obj) {
|
|
8553
|
-
if (Object.hasOwn(obj, key)) {
|
|
8554
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8555
|
-
obj[key] = obscure(obj[key]);
|
|
8556
|
-
}
|
|
8557
|
-
else if (obj[key] !== null && typeof obj[key] === "object") {
|
|
8558
|
-
obscureSensitiveData(obj[key]);
|
|
8559
|
-
}
|
|
8560
|
-
}
|
|
8561
|
-
}
|
|
8562
|
-
}
|
|
8563
|
-
}
|
|
8564
|
-
function tryFilterUrl(url) {
|
|
8565
|
-
if (!url)
|
|
8566
|
-
return "";
|
|
8567
|
-
try {
|
|
8568
|
-
const urlObj = new URL(url);
|
|
8569
|
-
if (urlObj.searchParams) {
|
|
8570
|
-
for (const key of urlObj.searchParams.keys()) {
|
|
8571
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8572
|
-
urlObj.searchParams.set(key, "******");
|
|
8573
|
-
}
|
|
8574
|
-
}
|
|
8575
|
-
}
|
|
8576
|
-
return urlObj.toString();
|
|
8577
|
-
}
|
|
8578
|
-
catch (e) {
|
|
8579
|
-
return url;
|
|
8580
|
-
}
|
|
8581
|
-
}
|
|
8582
|
-
|
|
8583
8476
|
/**
|
|
8584
8477
|
* I know we're not using most of the information from this class
|
|
8585
8478
|
* but it can be useful in the future if we will decide to display more stuff in our ui
|
|
@@ -8611,18 +8504,13 @@ class NetworkMessage {
|
|
|
8611
8504
|
}
|
|
8612
8505
|
getMessage() {
|
|
8613
8506
|
const { reqHs, resHs } = this.writeHeaders();
|
|
8614
|
-
const reqBody = this.method === 'GET'
|
|
8615
|
-
? JSON.stringify(sanitizeObject(this.getData)) : filterBody(this.requestData);
|
|
8616
8507
|
const request = {
|
|
8617
|
-
headers:
|
|
8618
|
-
body:
|
|
8619
|
-
};
|
|
8620
|
-
const response = {
|
|
8621
|
-
headers: filterHeaders(resHs),
|
|
8622
|
-
body: filterBody(this.response)
|
|
8508
|
+
headers: reqHs,
|
|
8509
|
+
body: this.method === 'GET' ? JSON.stringify(this.getData) : this.requestData,
|
|
8623
8510
|
};
|
|
8511
|
+
const response = { headers: resHs, body: this.response };
|
|
8624
8512
|
const messageInfo = this.sanitize({
|
|
8625
|
-
url:
|
|
8513
|
+
url: this.url,
|
|
8626
8514
|
method: this.method,
|
|
8627
8515
|
status: this.status,
|
|
8628
8516
|
request,
|
|
@@ -8938,10 +8826,9 @@ class ResponseProxyHandler {
|
|
|
8938
8826
|
if (typeof this.resp.body.getReader !== 'function') {
|
|
8939
8827
|
return;
|
|
8940
8828
|
}
|
|
8941
|
-
const
|
|
8942
|
-
const _getReader = clonedResp.body.getReader;
|
|
8829
|
+
const _getReader = this.resp.body.getReader;
|
|
8943
8830
|
// @ts-ignore
|
|
8944
|
-
|
|
8831
|
+
this.resp.body.getReader = () => {
|
|
8945
8832
|
const reader = _getReader.apply(this.resp.body);
|
|
8946
8833
|
// when readyState is already 4,
|
|
8947
8834
|
// it's not a chunked stream, or it had already been read.
|
|
@@ -9783,7 +9670,7 @@ class API {
|
|
|
9783
9670
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9784
9671
|
const doNotTrack = this.checkDoNotTrack();
|
|
9785
9672
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9786
|
-
trackerVersion: '16.3.0-beta.
|
|
9673
|
+
trackerVersion: '16.3.0-beta.2',
|
|
9787
9674
|
projectKey: this.options.projectKey,
|
|
9788
9675
|
doNotTrack,
|
|
9789
9676
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|