@openreplay/tracker 16.3.0-beta.0 → 16.3.0-beta.1
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 +50 -162
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +50 -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 +50 -162
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +50 -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
package/dist/cjs/entry.js
CHANGED
|
@@ -1469,6 +1469,43 @@ function simpleMerge(defaultObj, givenObj) {
|
|
|
1469
1469
|
}
|
|
1470
1470
|
return result;
|
|
1471
1471
|
}
|
|
1472
|
+
function throttleWithTrailing(fn, interval) {
|
|
1473
|
+
const lastCalls = new Map();
|
|
1474
|
+
const timeouts = new Map();
|
|
1475
|
+
const lastArgs = new Map();
|
|
1476
|
+
const throttled = function (key, ...args) {
|
|
1477
|
+
const now = Date.now();
|
|
1478
|
+
const lastCall = lastCalls.get(key) ?? 0;
|
|
1479
|
+
const remaining = interval - (now - lastCall);
|
|
1480
|
+
lastArgs.set(key, args);
|
|
1481
|
+
if (remaining <= 0) {
|
|
1482
|
+
if (timeouts.has(key)) {
|
|
1483
|
+
clearTimeout(timeouts.get(key));
|
|
1484
|
+
timeouts.delete(key);
|
|
1485
|
+
}
|
|
1486
|
+
lastCalls.set(key, now);
|
|
1487
|
+
fn(key, ...args);
|
|
1488
|
+
}
|
|
1489
|
+
else if (!timeouts.has(key)) {
|
|
1490
|
+
const timeoutId = setTimeout(() => {
|
|
1491
|
+
lastCalls.set(key, Date.now());
|
|
1492
|
+
timeouts.delete(key);
|
|
1493
|
+
const finalArgs = lastArgs.get(key);
|
|
1494
|
+
fn(key, ...finalArgs);
|
|
1495
|
+
}, remaining);
|
|
1496
|
+
timeouts.set(key, timeoutId);
|
|
1497
|
+
}
|
|
1498
|
+
};
|
|
1499
|
+
throttled.clear = () => {
|
|
1500
|
+
for (const timeout of timeouts.values()) {
|
|
1501
|
+
clearTimeout(timeout);
|
|
1502
|
+
}
|
|
1503
|
+
timeouts.clear();
|
|
1504
|
+
lastArgs.clear();
|
|
1505
|
+
lastCalls.clear();
|
|
1506
|
+
};
|
|
1507
|
+
return throttled;
|
|
1508
|
+
}
|
|
1472
1509
|
|
|
1473
1510
|
// Auto-generated, do not edit
|
|
1474
1511
|
/* eslint-disable */
|
|
@@ -4219,6 +4256,7 @@ class Observer {
|
|
|
4219
4256
|
this.inlineRemoteCss = false;
|
|
4220
4257
|
this.inlinerOptions = undefined;
|
|
4221
4258
|
this.domParser = new DOMParser();
|
|
4259
|
+
this.throttledSetNodeData = throttleWithTrailing((id, parentElement, data) => this.sendNodeData(id, parentElement, data), 30);
|
|
4222
4260
|
this.disableSprites = Boolean(options.disableSprites);
|
|
4223
4261
|
this.inlineRemoteCss = Boolean(options.inlineRemoteCss);
|
|
4224
4262
|
this.inlinerOptions = options.inlinerOptions;
|
|
@@ -4275,6 +4313,7 @@ class Observer {
|
|
|
4275
4313
|
this.indexes.length = 1;
|
|
4276
4314
|
this.attributesMap.clear();
|
|
4277
4315
|
this.textSet.clear();
|
|
4316
|
+
this.throttledSetNodeData.clear();
|
|
4278
4317
|
}
|
|
4279
4318
|
/**
|
|
4280
4319
|
* EXPERIMENTAL: Unbinds the removed nodes in case of iframe src change.
|
|
@@ -4530,7 +4569,7 @@ class Observer {
|
|
|
4530
4569
|
else if (isTextNode(node)) {
|
|
4531
4570
|
// for text node id != 0, hence parentID !== undefined and parent is Element
|
|
4532
4571
|
this.app.send(CreateTextNode(id, parentID, index));
|
|
4533
|
-
this.
|
|
4572
|
+
this.throttledSetNodeData(id, parent, node.data);
|
|
4534
4573
|
}
|
|
4535
4574
|
return true;
|
|
4536
4575
|
}
|
|
@@ -4551,7 +4590,7 @@ class Observer {
|
|
|
4551
4590
|
throw 'commitNode: node is not a text';
|
|
4552
4591
|
}
|
|
4553
4592
|
// for text node id != 0, hence parent is Element
|
|
4554
|
-
this.
|
|
4593
|
+
this.throttledSetNodeData(id, parent, node.data);
|
|
4555
4594
|
}
|
|
4556
4595
|
return true;
|
|
4557
4596
|
}
|
|
@@ -4594,6 +4633,7 @@ class Observer {
|
|
|
4594
4633
|
disconnect() {
|
|
4595
4634
|
this.observer.disconnect();
|
|
4596
4635
|
this.clear();
|
|
4636
|
+
this.throttledSetNodeData.clear();
|
|
4597
4637
|
}
|
|
4598
4638
|
}
|
|
4599
4639
|
|
|
@@ -5206,7 +5246,7 @@ class App {
|
|
|
5206
5246
|
this.stopCallbacks = [];
|
|
5207
5247
|
this.commitCallbacks = [];
|
|
5208
5248
|
this.activityState = ActivityState.NotActive;
|
|
5209
|
-
this.version = '16.3.0-beta.
|
|
5249
|
+
this.version = '16.3.0-beta.1'; // TODO: version compatability check inside each plugin.
|
|
5210
5250
|
this.socketMode = false;
|
|
5211
5251
|
this.compressionThreshold = 24 * 1000;
|
|
5212
5252
|
this.bc = null;
|
|
@@ -8438,152 +8478,6 @@ function isObject(thing) {
|
|
|
8438
8478
|
return thing !== null && typeof thing === 'object';
|
|
8439
8479
|
}
|
|
8440
8480
|
|
|
8441
|
-
const sensitiveParams = new Set([
|
|
8442
|
-
"password",
|
|
8443
|
-
"pass",
|
|
8444
|
-
"pwd",
|
|
8445
|
-
"mdp",
|
|
8446
|
-
"token",
|
|
8447
|
-
"bearer",
|
|
8448
|
-
"jwt",
|
|
8449
|
-
"api_key",
|
|
8450
|
-
"api-key",
|
|
8451
|
-
"apiKey",
|
|
8452
|
-
"secret",
|
|
8453
|
-
"ssn",
|
|
8454
|
-
"zip",
|
|
8455
|
-
"zipcode",
|
|
8456
|
-
"x-api-key",
|
|
8457
|
-
"www-authenticate",
|
|
8458
|
-
"x-csrf-token",
|
|
8459
|
-
"x-requested-with",
|
|
8460
|
-
"x-forwarded-for",
|
|
8461
|
-
"x-real-ip",
|
|
8462
|
-
"cookie",
|
|
8463
|
-
"authorization",
|
|
8464
|
-
"auth",
|
|
8465
|
-
"proxy-authorization",
|
|
8466
|
-
"set-cookie",
|
|
8467
|
-
"account_key",
|
|
8468
|
-
]);
|
|
8469
|
-
function numDigits(x) {
|
|
8470
|
-
return (Math.log10((x ^ (x >> 31)) - (x >> 31)) | 0) + 1;
|
|
8471
|
-
}
|
|
8472
|
-
function obscure(value) {
|
|
8473
|
-
if (typeof value === "number") {
|
|
8474
|
-
const digits = numDigits(value);
|
|
8475
|
-
return "9".repeat(digits);
|
|
8476
|
-
}
|
|
8477
|
-
if (typeof value === "string") {
|
|
8478
|
-
return value.replace(/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\s]/g, '*');
|
|
8479
|
-
}
|
|
8480
|
-
return value;
|
|
8481
|
-
}
|
|
8482
|
-
function filterHeaders(headers) {
|
|
8483
|
-
const filteredHeaders = {};
|
|
8484
|
-
if (Array.isArray(headers)) {
|
|
8485
|
-
headers.forEach(({ name, value }) => {
|
|
8486
|
-
if (sensitiveParams.has(name.toLowerCase())) {
|
|
8487
|
-
filteredHeaders[name] = obscure(value);
|
|
8488
|
-
}
|
|
8489
|
-
else {
|
|
8490
|
-
filteredHeaders[name] = value;
|
|
8491
|
-
}
|
|
8492
|
-
});
|
|
8493
|
-
}
|
|
8494
|
-
else {
|
|
8495
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
8496
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8497
|
-
filteredHeaders[key] = obscure(value);
|
|
8498
|
-
}
|
|
8499
|
-
else {
|
|
8500
|
-
filteredHeaders[key] = value;
|
|
8501
|
-
}
|
|
8502
|
-
}
|
|
8503
|
-
}
|
|
8504
|
-
return filteredHeaders;
|
|
8505
|
-
}
|
|
8506
|
-
function filterBody(body) {
|
|
8507
|
-
if (!body) {
|
|
8508
|
-
return body;
|
|
8509
|
-
}
|
|
8510
|
-
let parsedBody;
|
|
8511
|
-
let isJSON = false;
|
|
8512
|
-
try {
|
|
8513
|
-
parsedBody = JSON.parse(body);
|
|
8514
|
-
isJSON = true;
|
|
8515
|
-
}
|
|
8516
|
-
catch (e) {
|
|
8517
|
-
// not json
|
|
8518
|
-
}
|
|
8519
|
-
if (isJSON) {
|
|
8520
|
-
obscureSensitiveData(parsedBody);
|
|
8521
|
-
return JSON.stringify(parsedBody);
|
|
8522
|
-
}
|
|
8523
|
-
else {
|
|
8524
|
-
const isUrlSearch = typeof body === "string" && body.includes("?") && body.includes("=");
|
|
8525
|
-
if (isUrlSearch) {
|
|
8526
|
-
try {
|
|
8527
|
-
const params = new URLSearchParams(body);
|
|
8528
|
-
for (const key of params.keys()) {
|
|
8529
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8530
|
-
const value = obscure(params.get(key));
|
|
8531
|
-
params.set(key, value);
|
|
8532
|
-
}
|
|
8533
|
-
}
|
|
8534
|
-
return params.toString();
|
|
8535
|
-
}
|
|
8536
|
-
catch (e) {
|
|
8537
|
-
// not url query ?
|
|
8538
|
-
return body;
|
|
8539
|
-
}
|
|
8540
|
-
}
|
|
8541
|
-
else {
|
|
8542
|
-
// not json or url query
|
|
8543
|
-
return body;
|
|
8544
|
-
}
|
|
8545
|
-
}
|
|
8546
|
-
}
|
|
8547
|
-
function sanitizeObject(obj) {
|
|
8548
|
-
obscureSensitiveData(obj);
|
|
8549
|
-
return obj;
|
|
8550
|
-
}
|
|
8551
|
-
function obscureSensitiveData(obj) {
|
|
8552
|
-
if (Array.isArray(obj)) {
|
|
8553
|
-
obj.forEach(obscureSensitiveData);
|
|
8554
|
-
}
|
|
8555
|
-
else if (obj && typeof obj === "object") {
|
|
8556
|
-
for (const key in obj) {
|
|
8557
|
-
if (Object.hasOwn(obj, key)) {
|
|
8558
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8559
|
-
obj[key] = obscure(obj[key]);
|
|
8560
|
-
}
|
|
8561
|
-
else if (obj[key] !== null && typeof obj[key] === "object") {
|
|
8562
|
-
obscureSensitiveData(obj[key]);
|
|
8563
|
-
}
|
|
8564
|
-
}
|
|
8565
|
-
}
|
|
8566
|
-
}
|
|
8567
|
-
}
|
|
8568
|
-
function tryFilterUrl(url) {
|
|
8569
|
-
if (!url)
|
|
8570
|
-
return "";
|
|
8571
|
-
try {
|
|
8572
|
-
const urlObj = new URL(url);
|
|
8573
|
-
if (urlObj.searchParams) {
|
|
8574
|
-
for (const key of urlObj.searchParams.keys()) {
|
|
8575
|
-
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8576
|
-
urlObj.searchParams.set(key, "******");
|
|
8577
|
-
}
|
|
8578
|
-
}
|
|
8579
|
-
}
|
|
8580
|
-
return urlObj.toString();
|
|
8581
|
-
}
|
|
8582
|
-
catch (e) {
|
|
8583
|
-
return url;
|
|
8584
|
-
}
|
|
8585
|
-
}
|
|
8586
|
-
|
|
8587
8481
|
/**
|
|
8588
8482
|
* I know we're not using most of the information from this class
|
|
8589
8483
|
* but it can be useful in the future if we will decide to display more stuff in our ui
|
|
@@ -8615,18 +8509,13 @@ class NetworkMessage {
|
|
|
8615
8509
|
}
|
|
8616
8510
|
getMessage() {
|
|
8617
8511
|
const { reqHs, resHs } = this.writeHeaders();
|
|
8618
|
-
const reqBody = this.method === 'GET'
|
|
8619
|
-
? JSON.stringify(sanitizeObject(this.getData)) : filterBody(this.requestData);
|
|
8620
8512
|
const request = {
|
|
8621
|
-
headers:
|
|
8622
|
-
body:
|
|
8623
|
-
};
|
|
8624
|
-
const response = {
|
|
8625
|
-
headers: filterHeaders(resHs),
|
|
8626
|
-
body: filterBody(this.response)
|
|
8513
|
+
headers: reqHs,
|
|
8514
|
+
body: this.method === 'GET' ? JSON.stringify(this.getData) : this.requestData,
|
|
8627
8515
|
};
|
|
8516
|
+
const response = { headers: resHs, body: this.response };
|
|
8628
8517
|
const messageInfo = this.sanitize({
|
|
8629
|
-
url:
|
|
8518
|
+
url: this.url,
|
|
8630
8519
|
method: this.method,
|
|
8631
8520
|
status: this.status,
|
|
8632
8521
|
request,
|
|
@@ -8942,10 +8831,9 @@ class ResponseProxyHandler {
|
|
|
8942
8831
|
if (typeof this.resp.body.getReader !== 'function') {
|
|
8943
8832
|
return;
|
|
8944
8833
|
}
|
|
8945
|
-
const
|
|
8946
|
-
const _getReader = clonedResp.body.getReader;
|
|
8834
|
+
const _getReader = this.resp.body.getReader;
|
|
8947
8835
|
// @ts-ignore
|
|
8948
|
-
|
|
8836
|
+
this.resp.body.getReader = () => {
|
|
8949
8837
|
const reader = _getReader.apply(this.resp.body);
|
|
8950
8838
|
// when readyState is already 4,
|
|
8951
8839
|
// it's not a chunked stream, or it had already been read.
|
|
@@ -9787,7 +9675,7 @@ class API {
|
|
|
9787
9675
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9788
9676
|
const doNotTrack = this.checkDoNotTrack();
|
|
9789
9677
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9790
|
-
trackerVersion: '16.3.0-beta.
|
|
9678
|
+
trackerVersion: '16.3.0-beta.1',
|
|
9791
9679
|
projectKey: this.options.projectKey,
|
|
9792
9680
|
doNotTrack,
|
|
9793
9681
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|