@pendo/agent 2.320.3 → 2.320.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.
- package/dist/dom.esm.js +1 -1
- package/dist/pendo.module.js +421 -440
- package/dist/pendo.module.min.js +9 -2
- package/dist/servers.json +7 -7
- package/package.json +1 -1
package/dist/pendo.module.js
CHANGED
|
@@ -3967,8 +3967,8 @@ let SERVER = '';
|
|
|
3967
3967
|
let ASSET_HOST = '';
|
|
3968
3968
|
let ASSET_PATH = '';
|
|
3969
3969
|
let DESIGNER_SERVER = '';
|
|
3970
|
-
let VERSION = '2.320.
|
|
3971
|
-
let PACKAGE_VERSION = '2.320.
|
|
3970
|
+
let VERSION = '2.320.4_';
|
|
3971
|
+
let PACKAGE_VERSION = '2.320.4';
|
|
3972
3972
|
let LOADER = 'xhr';
|
|
3973
3973
|
/* eslint-enable web-sdk-eslint-rules/no-gulp-env-references */
|
|
3974
3974
|
/**
|
|
@@ -40598,12 +40598,12 @@ function TextCapture() {
|
|
|
40598
40598
|
return {
|
|
40599
40599
|
name: 'TextCapture',
|
|
40600
40600
|
initialize: init,
|
|
40601
|
-
teardown
|
|
40602
|
-
isEnabled
|
|
40603
|
-
isTextCapturable
|
|
40604
|
-
hasWhitelist
|
|
40601
|
+
teardown,
|
|
40602
|
+
isEnabled,
|
|
40603
|
+
isTextCapturable,
|
|
40604
|
+
hasWhitelist,
|
|
40605
40605
|
serializer: textSerializer,
|
|
40606
|
-
guideActivity
|
|
40606
|
+
guideActivity
|
|
40607
40607
|
};
|
|
40608
40608
|
// technically not idempotent but might actually be right. not sure.
|
|
40609
40609
|
function init(pendo, PluginAPI) {
|
|
@@ -40642,30 +40642,30 @@ function TextCapture() {
|
|
|
40642
40642
|
function guideActivity(pendo, event) {
|
|
40643
40643
|
if (!isEnabled())
|
|
40644
40644
|
return;
|
|
40645
|
-
|
|
40646
|
-
|
|
40645
|
+
const { _ } = pendo;
|
|
40646
|
+
const eventData = event.data[0];
|
|
40647
40647
|
if (eventData && eventData.type === 'guideActivity') {
|
|
40648
|
-
|
|
40648
|
+
const shownSteps = _.reduce(pendo.getActiveGuides({ channel: '*' }), (shown, guide) => {
|
|
40649
40649
|
if (guide.isShown()) {
|
|
40650
|
-
return shown.concat(_.filter(guide.steps,
|
|
40650
|
+
return shown.concat(_.filter(guide.steps, (step) => step.isShown()));
|
|
40651
40651
|
}
|
|
40652
40652
|
return shown;
|
|
40653
40653
|
}, []);
|
|
40654
40654
|
if (!shownSteps.length)
|
|
40655
40655
|
return;
|
|
40656
|
-
|
|
40657
|
-
|
|
40658
|
-
_.find(shownSteps,
|
|
40656
|
+
const findDomBlockInDomJson = pendo.BuildingBlocks.BuildingBlockGuides.findDomBlockInDomJson;
|
|
40657
|
+
let elementJson;
|
|
40658
|
+
_.find(shownSteps, (step) => {
|
|
40659
40659
|
if (!step.domJson)
|
|
40660
40660
|
return false;
|
|
40661
|
-
|
|
40661
|
+
elementJson = findDomBlockInDomJson(step.domJson, function (domJson) {
|
|
40662
40662
|
return domJson.props && domJson.props.id && domJson.props.id === eventData.props.ui_element_id;
|
|
40663
40663
|
});
|
|
40664
|
-
return
|
|
40664
|
+
return elementJson;
|
|
40665
40665
|
});
|
|
40666
|
-
if (!
|
|
40666
|
+
if (!elementJson)
|
|
40667
40667
|
return;
|
|
40668
|
-
eventData.props.ui_element_text =
|
|
40668
|
+
eventData.props.ui_element_text = elementJson.content;
|
|
40669
40669
|
}
|
|
40670
40670
|
}
|
|
40671
40671
|
function isEnabled() {
|
|
@@ -42375,22 +42375,22 @@ const startListening = (
|
|
|
42375
42375
|
};
|
|
42376
42376
|
|
|
42377
42377
|
function VocPortal() {
|
|
42378
|
-
|
|
42379
|
-
|
|
42378
|
+
let pendoGlobal;
|
|
42379
|
+
let pluginAPI;
|
|
42380
42380
|
return {
|
|
42381
42381
|
name: 'VocPortal',
|
|
42382
|
-
initialize
|
|
42383
|
-
routeHandlerLookup
|
|
42384
|
-
queryMessageHandler
|
|
42385
|
-
resizeMessageHandler
|
|
42386
|
-
teardown
|
|
42382
|
+
initialize,
|
|
42383
|
+
routeHandlerLookup,
|
|
42384
|
+
queryMessageHandler,
|
|
42385
|
+
resizeMessageHandler,
|
|
42386
|
+
teardown
|
|
42387
42387
|
};
|
|
42388
42388
|
function initialize(pendo, PluginAPI) {
|
|
42389
42389
|
pendoGlobal = pendo;
|
|
42390
42390
|
pluginAPI = PluginAPI;
|
|
42391
|
-
|
|
42391
|
+
const { frameId } = PluginAPI.EventTracer.addTracerIds({});
|
|
42392
42392
|
this.removeResizeEvent = pendoGlobal.attachEvent(window, 'resize', resizePortalIframe);
|
|
42393
|
-
startListening('VocPortal', frameId, routeHandlerLookup,
|
|
42393
|
+
startListening('VocPortal', frameId, routeHandlerLookup, () => '*');
|
|
42394
42394
|
}
|
|
42395
42395
|
function routeHandlerLookup(path) {
|
|
42396
42396
|
switch (path) {
|
|
@@ -42403,14 +42403,14 @@ function VocPortal() {
|
|
|
42403
42403
|
}
|
|
42404
42404
|
}
|
|
42405
42405
|
function resizePortalIframe() {
|
|
42406
|
-
|
|
42407
|
-
|
|
42406
|
+
const vocPortalRcContainer = document.getElementById('pendo-resource-center-container');
|
|
42407
|
+
const vocPortalRcDOM = pendoGlobal.dom(vocPortalRcContainer);
|
|
42408
42408
|
pluginAPI.sizeElements(vocPortalRcDOM);
|
|
42409
42409
|
}
|
|
42410
42410
|
function queryMessageHandler(_, responseHandler) {
|
|
42411
|
-
|
|
42412
|
-
|
|
42413
|
-
|
|
42411
|
+
const metadata = pendoGlobal.getSerializedMetadata();
|
|
42412
|
+
const sandBoxMode = !!pendoGlobal.designer || pluginAPI.store.getters['preview/isInPreviewMode']();
|
|
42413
|
+
const response = {
|
|
42414
42414
|
apiKey: pendoGlobal.apiKey,
|
|
42415
42415
|
url: pendoGlobal.url.externalizeURL(),
|
|
42416
42416
|
visitor: metadata.visitor,
|
|
@@ -42424,19 +42424,26 @@ function VocPortal() {
|
|
|
42424
42424
|
}
|
|
42425
42425
|
function resizeMessageHandler(msg) {
|
|
42426
42426
|
try {
|
|
42427
|
-
|
|
42428
|
-
|
|
42427
|
+
const { 'value': widthValue, 'unit': widthUnit, 'isImportant': widthIsImportant } = msg.data.width;
|
|
42428
|
+
const { 'value': heightValue, 'unit': heightUnit, 'isImportant': heightIsImportant } = msg.data.height;
|
|
42429
42429
|
if (typeof widthValue !== 'number' || typeof heightValue !== 'number') {
|
|
42430
42430
|
return;
|
|
42431
42431
|
}
|
|
42432
|
-
|
|
42432
|
+
const validUnits = ['px', '%', 'vh', 'vw'];
|
|
42433
42433
|
if (!pendoGlobal._.contains(validUnits, widthUnit) || !pendoGlobal._.contains(validUnits, heightUnit)) {
|
|
42434
42434
|
return;
|
|
42435
42435
|
}
|
|
42436
|
-
|
|
42437
|
-
|
|
42438
|
-
|
|
42439
|
-
pluginAPI.util.addInlineStyles('pendo-voc-portal-styles',
|
|
42436
|
+
const width = `${widthValue}${widthUnit}${widthIsImportant ? ' !important' : ''}`;
|
|
42437
|
+
const height = `${heightValue}${heightUnit}${heightIsImportant ? ' !important' : ''}`;
|
|
42438
|
+
const container = document.getElementById('pendo-resource-center-container');
|
|
42439
|
+
pluginAPI.util.addInlineStyles('pendo-voc-portal-styles', `#pendo-resource-center-container:has(iframe[src*="portal"][src*="mode=rc"]) {
|
|
42440
|
+
width: ${width};
|
|
42441
|
+
height: ${height};
|
|
42442
|
+
._pendo-step-container-size {
|
|
42443
|
+
width: ${width};
|
|
42444
|
+
height: ${height};
|
|
42445
|
+
}
|
|
42446
|
+
}`, container);
|
|
42440
42447
|
resizePortalIframe();
|
|
42441
42448
|
}
|
|
42442
42449
|
catch (err) {
|
|
@@ -46485,10 +46492,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
46485
46492
|
removes: [{ index: index2 }]
|
|
46486
46493
|
});
|
|
46487
46494
|
}
|
|
46488
|
-
|
|
46489
|
-
return target.apply(thisArg, argumentsList);
|
|
46490
|
-
} catch (e2) {
|
|
46491
|
-
}
|
|
46495
|
+
return target.apply(thisArg, argumentsList);
|
|
46492
46496
|
}
|
|
46493
46497
|
)
|
|
46494
46498
|
});
|
|
@@ -46617,10 +46621,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
46617
46621
|
]
|
|
46618
46622
|
});
|
|
46619
46623
|
}
|
|
46620
|
-
|
|
46621
|
-
return target.apply(thisArg, argumentsList);
|
|
46622
|
-
} catch (e2) {
|
|
46623
|
-
}
|
|
46624
|
+
return target.apply(thisArg, argumentsList);
|
|
46624
46625
|
}
|
|
46625
46626
|
)
|
|
46626
46627
|
}
|
|
@@ -48626,6 +48627,61 @@ var n;
|
|
|
48626
48627
|
}(n || (n = {}));
|
|
48627
48628
|
return record; }
|
|
48628
48629
|
|
|
48630
|
+
var SessionRecorderBuffer = /** @class */ (function () {
|
|
48631
|
+
function SessionRecorderBuffer(interval, maxCount) {
|
|
48632
|
+
if (maxCount === void 0) { maxCount = Infinity; }
|
|
48633
|
+
this.data = [];
|
|
48634
|
+
this.sequenceNumber = 0;
|
|
48635
|
+
this.interval = interval;
|
|
48636
|
+
this.maxCount = maxCount;
|
|
48637
|
+
this.doubledMaxCount = maxCount * 2;
|
|
48638
|
+
}
|
|
48639
|
+
SessionRecorderBuffer.prototype.isEmpty = function () {
|
|
48640
|
+
return this.data.length === 0;
|
|
48641
|
+
};
|
|
48642
|
+
SessionRecorderBuffer.prototype.count = function () {
|
|
48643
|
+
return this.data.length;
|
|
48644
|
+
};
|
|
48645
|
+
SessionRecorderBuffer.prototype.clear = function () {
|
|
48646
|
+
this.data.length = 0;
|
|
48647
|
+
};
|
|
48648
|
+
SessionRecorderBuffer.prototype.clearSequence = function () {
|
|
48649
|
+
this.sequenceNumber = 0;
|
|
48650
|
+
};
|
|
48651
|
+
SessionRecorderBuffer.prototype.push = function (event) {
|
|
48652
|
+
this.data.push(event);
|
|
48653
|
+
this.checkRateLimit();
|
|
48654
|
+
};
|
|
48655
|
+
SessionRecorderBuffer.prototype.pack = function (envelope, _) {
|
|
48656
|
+
var eventsToSend = this.data.splice(0, this.maxCount);
|
|
48657
|
+
envelope.recordingPayload = eventsToSend;
|
|
48658
|
+
envelope.sequence = this.sequenceNumber;
|
|
48659
|
+
envelope.recordingPayloadCount = eventsToSend.length;
|
|
48660
|
+
if (eventsToSend.length) {
|
|
48661
|
+
envelope.browserTime = eventsToSend[0].timestamp;
|
|
48662
|
+
}
|
|
48663
|
+
envelope.recordingPayloadMetadata = _.map(eventsToSend, function (event) {
|
|
48664
|
+
var metadata = _.pick(event, 'type', 'timestamp');
|
|
48665
|
+
if (event.data) {
|
|
48666
|
+
metadata.data = _.pick(event.data, 'source', 'type', 'x', 'y', 'id', 'height', 'width', 'href');
|
|
48667
|
+
}
|
|
48668
|
+
return metadata;
|
|
48669
|
+
});
|
|
48670
|
+
this.sequenceNumber += eventsToSend.length;
|
|
48671
|
+
return envelope;
|
|
48672
|
+
};
|
|
48673
|
+
SessionRecorderBuffer.prototype.checkRateLimit = function () {
|
|
48674
|
+
var length = this.data.length;
|
|
48675
|
+
if (length >= this.doubledMaxCount && length % this.maxCount === 0) {
|
|
48676
|
+
var elapsed = this.data[length - 1].timestamp - this.data[length - this.doubledMaxCount].timestamp;
|
|
48677
|
+
if (elapsed <= this.interval && this.onRateLimit) {
|
|
48678
|
+
this.onRateLimit();
|
|
48679
|
+
}
|
|
48680
|
+
}
|
|
48681
|
+
};
|
|
48682
|
+
return SessionRecorderBuffer;
|
|
48683
|
+
}());
|
|
48684
|
+
|
|
48629
48685
|
var __assign = function() {
|
|
48630
48686
|
__assign = Object.assign || function __assign(t) {
|
|
48631
48687
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
@@ -48692,61 +48748,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
48692
48748
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
48693
48749
|
};
|
|
48694
48750
|
|
|
48695
|
-
var SessionRecorderBuffer = /** @class */ (function () {
|
|
48696
|
-
function SessionRecorderBuffer(interval, maxCount) {
|
|
48697
|
-
if (maxCount === void 0) { maxCount = Infinity; }
|
|
48698
|
-
this.data = [];
|
|
48699
|
-
this.sequenceNumber = 0;
|
|
48700
|
-
this.interval = interval;
|
|
48701
|
-
this.maxCount = maxCount;
|
|
48702
|
-
this.doubledMaxCount = maxCount * 2;
|
|
48703
|
-
}
|
|
48704
|
-
SessionRecorderBuffer.prototype.isEmpty = function () {
|
|
48705
|
-
return this.data.length === 0;
|
|
48706
|
-
};
|
|
48707
|
-
SessionRecorderBuffer.prototype.count = function () {
|
|
48708
|
-
return this.data.length;
|
|
48709
|
-
};
|
|
48710
|
-
SessionRecorderBuffer.prototype.clear = function () {
|
|
48711
|
-
this.data.length = 0;
|
|
48712
|
-
};
|
|
48713
|
-
SessionRecorderBuffer.prototype.clearSequence = function () {
|
|
48714
|
-
this.sequenceNumber = 0;
|
|
48715
|
-
};
|
|
48716
|
-
SessionRecorderBuffer.prototype.push = function (event) {
|
|
48717
|
-
this.data.push(event);
|
|
48718
|
-
this.checkRateLimit();
|
|
48719
|
-
};
|
|
48720
|
-
SessionRecorderBuffer.prototype.pack = function (envelope, _) {
|
|
48721
|
-
var eventsToSend = this.data.splice(0, this.maxCount);
|
|
48722
|
-
envelope.recordingPayload = eventsToSend;
|
|
48723
|
-
envelope.sequence = this.sequenceNumber;
|
|
48724
|
-
envelope.recordingPayloadCount = eventsToSend.length;
|
|
48725
|
-
if (eventsToSend.length) {
|
|
48726
|
-
envelope.browserTime = eventsToSend[0].timestamp;
|
|
48727
|
-
}
|
|
48728
|
-
envelope.recordingPayloadMetadata = _.map(eventsToSend, function (event) {
|
|
48729
|
-
var metadata = _.pick(event, 'type', 'timestamp');
|
|
48730
|
-
if (event.data) {
|
|
48731
|
-
metadata.data = _.pick(event.data, 'source', 'type', 'x', 'y', 'id', 'height', 'width', 'href');
|
|
48732
|
-
}
|
|
48733
|
-
return metadata;
|
|
48734
|
-
});
|
|
48735
|
-
this.sequenceNumber += eventsToSend.length;
|
|
48736
|
-
return envelope;
|
|
48737
|
-
};
|
|
48738
|
-
SessionRecorderBuffer.prototype.checkRateLimit = function () {
|
|
48739
|
-
var length = this.data.length;
|
|
48740
|
-
if (length >= this.doubledMaxCount && length % this.maxCount === 0) {
|
|
48741
|
-
var elapsed = this.data[length - 1].timestamp - this.data[length - this.doubledMaxCount].timestamp;
|
|
48742
|
-
if (elapsed <= this.interval && this.onRateLimit) {
|
|
48743
|
-
this.onRateLimit();
|
|
48744
|
-
}
|
|
48745
|
-
}
|
|
48746
|
-
};
|
|
48747
|
-
return SessionRecorderBuffer;
|
|
48748
|
-
}());
|
|
48749
|
-
|
|
48750
48751
|
var RECORDING_CONFIG_WORKERURL$1 = 'recording.workerUrl';
|
|
48751
48752
|
var MAX_SIZE = 2000000;
|
|
48752
48753
|
var RESOURCE_CACHING$1 = 'resourceCaching';
|
|
@@ -48981,33 +48982,33 @@ function maskText(options, text, element) {
|
|
|
48981
48982
|
return text;
|
|
48982
48983
|
}
|
|
48983
48984
|
|
|
48984
|
-
|
|
48985
|
-
|
|
48986
|
-
|
|
48987
|
-
|
|
48988
|
-
|
|
48989
|
-
|
|
48990
|
-
|
|
48991
|
-
|
|
48992
|
-
|
|
48993
|
-
|
|
48994
|
-
|
|
48995
|
-
|
|
48996
|
-
|
|
48997
|
-
|
|
48998
|
-
|
|
48999
|
-
|
|
49000
|
-
|
|
49001
|
-
|
|
49002
|
-
|
|
48985
|
+
const RECORDING_CONFIG = 'recording';
|
|
48986
|
+
const RECORDING_CONFIG_ENABLED = 'recording.enabled';
|
|
48987
|
+
const RECORDING_CONFIG_AUTO_START = 'recording.autoStart';
|
|
48988
|
+
const RECORDING_CONFIG_WORKERURL = 'recording.workerUrl';
|
|
48989
|
+
const RECORDING_CONFIG_ON_RECORDING_START = 'recording.onRecordingStart';
|
|
48990
|
+
const RECORDING_CONFIG_ON_RECORDING_STOP = 'recording.onRecordingStop';
|
|
48991
|
+
const RECORDING_CONFIG_WORKER_OVERRIDE = 'recording.workerOverride';
|
|
48992
|
+
const RECORDING_CONFIG_TREAT_IFRAME_AS_ROOT = 'recording.treatIframeAsRoot';
|
|
48993
|
+
const RECORDING_CONFIG_DISABLE_UNLOAD = 'recording.disableUnload';
|
|
48994
|
+
const RESOURCE_CACHING = 'resourceCaching';
|
|
48995
|
+
const ONE_DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000;
|
|
48996
|
+
const ONE_MINUTE_IN_MILLISECONDS = 60 * 1000;
|
|
48997
|
+
const THIRTY_MINUTES = 1000 * 60 * 30;
|
|
48998
|
+
const ONE_HUNDRED_MB_IN_BYTES = 100 * 1024 * 1024;
|
|
48999
|
+
const SESSION_RECORDING_ID = 'pendo_srId';
|
|
49000
|
+
const SESSION_RECORDING_LAST_USER_INTERACTION_EVENT = 'pendo_srLastUserInteractionEvent';
|
|
49001
|
+
const SEND_INTERVAL = 5000;
|
|
49002
|
+
const MAX_SEND_COUNT = 20000;
|
|
49003
|
+
const EVENT_TYPES = {
|
|
49003
49004
|
INCREMENTAL_SOURCE_MUTATION: 0,
|
|
49004
49005
|
FULL_SNAPSHOT: 2,
|
|
49005
49006
|
INCREMENTAL_SNAPSHOT: 3,
|
|
49006
49007
|
META: 4,
|
|
49007
49008
|
INCREMENTAL_SOURCE_INPUT: 5
|
|
49008
49009
|
};
|
|
49009
|
-
|
|
49010
|
-
|
|
49010
|
+
class SessionRecorder {
|
|
49011
|
+
constructor(rrwebRecord, WorkerClass) {
|
|
49011
49012
|
this.name = 'Replay';
|
|
49012
49013
|
this.record = rrwebRecord;
|
|
49013
49014
|
this.WorkerClass = WorkerClass;
|
|
@@ -49015,8 +49016,8 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49015
49016
|
this.eventsSinceLastKeyFrame = 0;
|
|
49016
49017
|
this.currentRecordingSize = 0;
|
|
49017
49018
|
}
|
|
49018
|
-
|
|
49019
|
-
|
|
49019
|
+
addConfigOptions() {
|
|
49020
|
+
const cf = this.api.ConfigReader;
|
|
49020
49021
|
cf.addOption(RECORDING_CONFIG, [cf.sources.PENDO_CONFIG_SRC], {});
|
|
49021
49022
|
/**
|
|
49022
49023
|
* Determines if replay will immediately begin collecting data. If false, you can resume collecting
|
|
@@ -49102,12 +49103,12 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49102
49103
|
*/
|
|
49103
49104
|
cf.addOption(RECORDING_CONFIG_TREAT_IFRAME_AS_ROOT, [cf.sources.SNIPPET_SRC], undefined);
|
|
49104
49105
|
cf.addOption(RESOURCE_CACHING, [cf.sources.PENDO_CONFIG_SRC], undefined);
|
|
49105
|
-
}
|
|
49106
|
-
|
|
49106
|
+
}
|
|
49107
|
+
initialize(pendo, PluginAPI) {
|
|
49107
49108
|
this.pendo = pendo;
|
|
49108
49109
|
this.api = PluginAPI;
|
|
49109
|
-
|
|
49110
|
-
|
|
49110
|
+
const bind = this.pendo._.bind;
|
|
49111
|
+
const configReader = this.api.ConfigReader;
|
|
49111
49112
|
this.buffer = new SessionRecorderBuffer(SEND_INTERVAL, MAX_SEND_COUNT);
|
|
49112
49113
|
this.buffer.onRateLimit = bind(this.rateLimitExceeded, this);
|
|
49113
49114
|
this.transport = new Transport(this.WorkerClass, this.pendo, this.api);
|
|
@@ -49125,8 +49126,8 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49125
49126
|
? configReader.get(RECORDING_CONFIG_ON_RECORDING_START) : function () { };
|
|
49126
49127
|
this.onRecordingStop = this.pendo._.isFunction(configReader.get(RECORDING_CONFIG_ON_RECORDING_STOP))
|
|
49127
49128
|
? configReader.get(RECORDING_CONFIG_ON_RECORDING_STOP) : function () { };
|
|
49128
|
-
|
|
49129
|
-
|
|
49129
|
+
let isSessionReplayEnabled = false;
|
|
49130
|
+
const snippetOverrideValue = configReader.get(RECORDING_CONFIG_ENABLED);
|
|
49130
49131
|
// The snippet config value should take precedence over whatever value the backend returns,
|
|
49131
49132
|
// but ONLY for replay being enabled - all other values should be taken from the backend
|
|
49132
49133
|
if (this.pendo._.isBoolean(snippetOverrideValue)) {
|
|
@@ -49145,7 +49146,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49145
49146
|
this.api.log.info('Session Replay is disabled because excludeNonGuideAnalytics is enabled');
|
|
49146
49147
|
return;
|
|
49147
49148
|
}
|
|
49148
|
-
|
|
49149
|
+
const sessionIdKey = this.sessionIdKey = `${SESSION_RECORDING_ID}.${this.pendo.apiKey}`;
|
|
49149
49150
|
this.pendo.recording = {
|
|
49150
49151
|
start: bind(this.start, this),
|
|
49151
49152
|
stop: bind(this.stop, this)
|
|
@@ -49186,8 +49187,8 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49186
49187
|
* @label SESSION_RECORDING_LAST_USER_INTERACTION_EVENT
|
|
49187
49188
|
*/
|
|
49188
49189
|
this.api.agentStorage.registry.addSession(SESSION_RECORDING_LAST_USER_INTERACTION_EVENT);
|
|
49189
|
-
}
|
|
49190
|
-
|
|
49190
|
+
}
|
|
49191
|
+
teardown() {
|
|
49191
49192
|
delete this.pendo.recording;
|
|
49192
49193
|
delete this.allowStart;
|
|
49193
49194
|
this.pendo._.each(this.subscriptions, function (unsubscribe) {
|
|
@@ -49197,36 +49198,35 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49197
49198
|
this.subscriptions.length = 0;
|
|
49198
49199
|
this.stop();
|
|
49199
49200
|
this.transport.stop();
|
|
49200
|
-
}
|
|
49201
|
-
|
|
49201
|
+
}
|
|
49202
|
+
ready() {
|
|
49202
49203
|
if (this.api.ConfigReader.get(RECORDING_CONFIG_AUTO_START) !== false) {
|
|
49203
49204
|
this.start();
|
|
49204
49205
|
}
|
|
49205
|
-
}
|
|
49206
|
-
|
|
49207
|
-
var _this = this;
|
|
49206
|
+
}
|
|
49207
|
+
addPageLifecycleListeners() {
|
|
49208
49208
|
// It's important these event listeners use the capture phase, so making it explicit.
|
|
49209
|
-
|
|
49210
|
-
this.pendo._.each(['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'],
|
|
49211
|
-
|
|
49209
|
+
const useCapture = true;
|
|
49210
|
+
this.pendo._.each(['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'], (type) => {
|
|
49211
|
+
this.pageLifecycleListeners.push(this.api.attachEventInternal(window, type, this.pendo._.bind(this.checkPageLifecycleState, this), useCapture));
|
|
49212
49212
|
});
|
|
49213
|
-
}
|
|
49214
|
-
|
|
49213
|
+
}
|
|
49214
|
+
removePageLifecycleListeners() {
|
|
49215
49215
|
this.pendo._.each(this.pageLifecycleListeners, function (teardownFn) {
|
|
49216
49216
|
teardownFn();
|
|
49217
49217
|
});
|
|
49218
49218
|
this.pageLifecycleListeners = [];
|
|
49219
|
-
}
|
|
49220
|
-
|
|
49221
|
-
|
|
49219
|
+
}
|
|
49220
|
+
checkPageLifecycleState() {
|
|
49221
|
+
const state = this.getPageLifecycleState();
|
|
49222
49222
|
if (state === 'active' || state === 'passive') {
|
|
49223
49223
|
if (!this.isRecording() && this.allowStart) {
|
|
49224
49224
|
this.removePageLifecycleListeners();
|
|
49225
49225
|
this.ready();
|
|
49226
49226
|
}
|
|
49227
49227
|
}
|
|
49228
|
-
}
|
|
49229
|
-
|
|
49228
|
+
}
|
|
49229
|
+
getPageLifecycleState() {
|
|
49230
49230
|
if (document.visibilityState === 'hidden') {
|
|
49231
49231
|
return 'hidden';
|
|
49232
49232
|
}
|
|
@@ -49234,9 +49234,8 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49234
49234
|
return 'active';
|
|
49235
49235
|
}
|
|
49236
49236
|
return 'passive';
|
|
49237
|
-
}
|
|
49238
|
-
|
|
49239
|
-
var _this = this;
|
|
49237
|
+
}
|
|
49238
|
+
changeIdentity(identifyEvent) {
|
|
49240
49239
|
if (!this.allowStart)
|
|
49241
49240
|
return;
|
|
49242
49241
|
clearTimeout(this._changeIdentityTimer);
|
|
@@ -49251,56 +49250,55 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49251
49250
|
}
|
|
49252
49251
|
this.visitorId = identifyEvent.data[0].visitor_id;
|
|
49253
49252
|
this.accountId = identifyEvent.data[0].account_id;
|
|
49254
|
-
this._changeIdentityTimer = setTimeout$1(
|
|
49255
|
-
|
|
49253
|
+
this._changeIdentityTimer = setTimeout$1(() => {
|
|
49254
|
+
this._start();
|
|
49256
49255
|
}, 500);
|
|
49257
|
-
}
|
|
49258
|
-
|
|
49259
|
-
|
|
49256
|
+
}
|
|
49257
|
+
changeMetadata(metadataEvent) {
|
|
49258
|
+
const { hashChanged, options } = metadataEvent.data[0];
|
|
49260
49259
|
if (this.allowStart && hashChanged) {
|
|
49261
49260
|
clearTimeout(this._changeIdentityTimer);
|
|
49262
49261
|
this.visitorId = options.visitor.id;
|
|
49263
49262
|
this.accountId = options.account.id;
|
|
49264
49263
|
return this.checkVisitorEligibility();
|
|
49265
49264
|
}
|
|
49266
|
-
}
|
|
49267
|
-
|
|
49268
|
-
var _this = this;
|
|
49265
|
+
}
|
|
49266
|
+
checkVisitorEligibility(continuationCallback) {
|
|
49269
49267
|
if (!this.isRecording() && this.pendo._.isNull(this.visitorId) && this.pendo._.isNull(this.accountId))
|
|
49270
49268
|
return;
|
|
49271
49269
|
this.isCheckingVisitorEligibility = true;
|
|
49272
|
-
return this.fetchVisitorConfig().then(
|
|
49273
|
-
if ((!visitorConfig || !visitorConfig.enable) &&
|
|
49274
|
-
|
|
49270
|
+
return this.fetchVisitorConfig().then(visitorConfig => {
|
|
49271
|
+
if ((!visitorConfig || !visitorConfig.enable) && this.isRecording()) {
|
|
49272
|
+
this.stop();
|
|
49275
49273
|
}
|
|
49276
|
-
if (visitorConfig && visitorConfig.enable &&
|
|
49274
|
+
if (visitorConfig && visitorConfig.enable && this.isRecording()) {
|
|
49277
49275
|
if (continuationCallback) {
|
|
49278
|
-
continuationCallback.call(
|
|
49276
|
+
continuationCallback.call(this);
|
|
49279
49277
|
}
|
|
49280
|
-
|
|
49278
|
+
this.api.Events.trigger('recording:unpaused');
|
|
49281
49279
|
}
|
|
49282
|
-
if (visitorConfig && visitorConfig.enable && !
|
|
49283
|
-
|
|
49280
|
+
if (visitorConfig && visitorConfig.enable && !this.isRecording()) {
|
|
49281
|
+
this._startRecordingForVisitor(visitorConfig);
|
|
49284
49282
|
}
|
|
49285
|
-
|
|
49286
|
-
})
|
|
49287
|
-
|
|
49288
|
-
|
|
49289
|
-
|
|
49283
|
+
this.isCheckingVisitorEligibility = false;
|
|
49284
|
+
}).catch((e) => {
|
|
49285
|
+
this.isCheckingVisitorEligibility = false;
|
|
49286
|
+
this.api.log.critical('Failed to re-fetch recording config', { error: e });
|
|
49287
|
+
this.logStopReason('VISITOR_CONFIG_ERROR');
|
|
49290
49288
|
});
|
|
49291
|
-
}
|
|
49292
|
-
|
|
49289
|
+
}
|
|
49290
|
+
snapshot() {
|
|
49293
49291
|
if (!this.isRecording())
|
|
49294
49292
|
return;
|
|
49295
49293
|
this.send();
|
|
49296
49294
|
this.record.takeFullSnapshot();
|
|
49297
|
-
}
|
|
49298
|
-
|
|
49295
|
+
}
|
|
49296
|
+
isRecording() {
|
|
49299
49297
|
return this.interval != null;
|
|
49300
|
-
}
|
|
49301
|
-
|
|
49302
|
-
|
|
49303
|
-
|
|
49298
|
+
}
|
|
49299
|
+
recordingConfig(visitorConfig) {
|
|
49300
|
+
const recordingOptions = this.pendo._.extend({}, this.config.options, visitorConfig);
|
|
49301
|
+
const maskOptions = {
|
|
49304
49302
|
maskAllText: recordingOptions.privateByDefault != null ? recordingOptions.privateByDefault : true,
|
|
49305
49303
|
maskTextSelector: ['.pendo-sr-mask'].concat(recordingOptions.maskedSelectors || []).join(','),
|
|
49306
49304
|
unmaskTextSelector: ['.pendo-sr-unmask'].concat(recordingOptions.unmaskedSelectors || []).join(','),
|
|
@@ -49315,9 +49313,9 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49315
49313
|
password: true,
|
|
49316
49314
|
tel: true
|
|
49317
49315
|
});
|
|
49318
|
-
|
|
49319
|
-
|
|
49320
|
-
|
|
49316
|
+
const blockedSelectors = ['.pendo-ignore', '.pendo-sr-ignore'].concat(recordingOptions.blockedSelectors || []);
|
|
49317
|
+
const hiddenSelectors = ['.pendo-sr-hide'].concat(recordingOptions.hiddenSelectors || []);
|
|
49318
|
+
const config = {
|
|
49321
49319
|
maskInputFn: this.pendo._.partial(maskInput, maskOptions),
|
|
49322
49320
|
maskTextFn: this.pendo._.partial(maskText, maskOptions),
|
|
49323
49321
|
maskTextSelector: '*',
|
|
@@ -49331,7 +49329,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49331
49329
|
emitFromIframe: !!this.api.ConfigReader.get(RECORDING_CONFIG_TREAT_IFRAME_AS_ROOT)
|
|
49332
49330
|
};
|
|
49333
49331
|
return config;
|
|
49334
|
-
}
|
|
49332
|
+
}
|
|
49335
49333
|
/**
|
|
49336
49334
|
* Used to start collecting replay data.
|
|
49337
49335
|
*
|
|
@@ -49341,71 +49339,67 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49341
49339
|
* @example
|
|
49342
49340
|
* pendo.recording.start()
|
|
49343
49341
|
*/
|
|
49344
|
-
|
|
49342
|
+
start() {
|
|
49345
49343
|
this._restartPtm = this.api.analytics.ptm().pause();
|
|
49346
49344
|
this.allowStart = true;
|
|
49347
49345
|
this.visitorId = this.pendo.get_visitor_id();
|
|
49348
49346
|
this.accountId = this.pendo.get_account_id();
|
|
49349
49347
|
this._start();
|
|
49350
|
-
}
|
|
49351
|
-
|
|
49348
|
+
}
|
|
49349
|
+
_markEvents(events) {
|
|
49352
49350
|
if (!this.recordingId || !this.isRecording())
|
|
49353
49351
|
return;
|
|
49354
|
-
for (var
|
|
49355
|
-
var e = events_1[_i];
|
|
49352
|
+
for (var e of events) {
|
|
49356
49353
|
if ((e.visitor_id === this.visitorId || e.visitorId === this.visitorId) && e.type !== 'identify') {
|
|
49357
49354
|
e.recordingId = this.recordingId;
|
|
49358
49355
|
e.recordingSessionId = this.sessionId(this.recordingId);
|
|
49359
49356
|
}
|
|
49360
49357
|
}
|
|
49361
|
-
}
|
|
49362
|
-
|
|
49358
|
+
}
|
|
49359
|
+
restartPtm() {
|
|
49363
49360
|
if (this.pendo._.isFunction(this._restartPtm)) {
|
|
49364
49361
|
this._markEvents(this.pendo.buffers.events);
|
|
49365
|
-
for (var
|
|
49366
|
-
var silo = _a[_i];
|
|
49362
|
+
for (var silo of this.pendo.buffers.silos) {
|
|
49367
49363
|
this._markEvents(silo);
|
|
49368
49364
|
}
|
|
49369
49365
|
this._restartPtm();
|
|
49370
49366
|
this._restartPtm = null;
|
|
49371
49367
|
}
|
|
49372
|
-
}
|
|
49373
|
-
|
|
49374
|
-
var _this = this;
|
|
49368
|
+
}
|
|
49369
|
+
_start() {
|
|
49375
49370
|
if (this.isRecording())
|
|
49376
49371
|
return;
|
|
49377
49372
|
if (!this.pendo.isSendingEvents())
|
|
49378
49373
|
return;
|
|
49379
49374
|
if (!this.allowStart)
|
|
49380
49375
|
return;
|
|
49381
|
-
return this.fetchVisitorConfig().then(
|
|
49382
|
-
if (!
|
|
49376
|
+
return this.fetchVisitorConfig().then(visitorConfig => {
|
|
49377
|
+
if (!this.allowStart)
|
|
49383
49378
|
return;
|
|
49384
49379
|
if (!visitorConfig || !visitorConfig.enable) {
|
|
49385
|
-
|
|
49386
|
-
|
|
49380
|
+
this.restartPtm();
|
|
49381
|
+
this.logStopReason('VISITOR_DISABLED');
|
|
49387
49382
|
return;
|
|
49388
49383
|
}
|
|
49389
|
-
|
|
49390
|
-
})
|
|
49391
|
-
|
|
49384
|
+
this._startRecordingForVisitor(visitorConfig);
|
|
49385
|
+
}).catch((e) => {
|
|
49386
|
+
this.restartPtm();
|
|
49392
49387
|
if (e && /Failed to fetch/.test(e.toString())) {
|
|
49393
49388
|
return;
|
|
49394
49389
|
}
|
|
49395
|
-
|
|
49390
|
+
this.api.log.critical('Failed to fetch recording config', {
|
|
49396
49391
|
error: e,
|
|
49397
|
-
visitorId:
|
|
49398
|
-
accountId:
|
|
49399
|
-
url:
|
|
49392
|
+
visitorId: this.visitorId,
|
|
49393
|
+
accountId: this.accountId,
|
|
49394
|
+
url: this.pendo.url.get()
|
|
49400
49395
|
});
|
|
49401
|
-
|
|
49396
|
+
this.logStopReason('VISITOR_CONFIG_ERROR');
|
|
49402
49397
|
});
|
|
49403
|
-
}
|
|
49404
|
-
|
|
49405
|
-
var _this = this;
|
|
49398
|
+
}
|
|
49399
|
+
_startRecordingForVisitor(visitorConfig) {
|
|
49406
49400
|
this.api.Events.trigger('recording:unpaused');
|
|
49407
49401
|
this.transport.start(this.config);
|
|
49408
|
-
|
|
49402
|
+
const disableFallback = this.pendo._.get(this.config, 'disableFallback', true);
|
|
49409
49403
|
if (disableFallback && !this.transport.worker) {
|
|
49410
49404
|
this.restartPtm();
|
|
49411
49405
|
this.pendo.log('Worker failed to start and main thread fallback is disabled. Recording prevented from starting.');
|
|
@@ -49417,9 +49411,9 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49417
49411
|
this.visitorConfig = visitorConfig;
|
|
49418
49412
|
this.clearOldSessionId();
|
|
49419
49413
|
this.sendQueue.start();
|
|
49420
|
-
this.interval = setInterval(
|
|
49421
|
-
if (!
|
|
49422
|
-
|
|
49414
|
+
this.interval = setInterval(() => {
|
|
49415
|
+
if (!this.sendQueue.failed()) {
|
|
49416
|
+
this.send();
|
|
49423
49417
|
}
|
|
49424
49418
|
}, SEND_INTERVAL);
|
|
49425
49419
|
var config = this.recordingConfig(visitorConfig);
|
|
@@ -49434,8 +49428,8 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49434
49428
|
this.restartPtm();
|
|
49435
49429
|
this.logStopReason('RECORDING_ERROR');
|
|
49436
49430
|
}
|
|
49437
|
-
}
|
|
49438
|
-
|
|
49431
|
+
}
|
|
49432
|
+
_sendIds() {
|
|
49439
49433
|
if (window != window.top)
|
|
49440
49434
|
return;
|
|
49441
49435
|
this.api.frames.getChannel().postMessage({
|
|
@@ -49444,16 +49438,16 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49444
49438
|
_sessionId: this._sessionId,
|
|
49445
49439
|
topId: this.api.store.state.frames.topId
|
|
49446
49440
|
});
|
|
49447
|
-
}
|
|
49448
|
-
|
|
49441
|
+
}
|
|
49442
|
+
_refreshIds() {
|
|
49449
49443
|
if (window == window.top)
|
|
49450
49444
|
return;
|
|
49451
49445
|
this.api.frames.getChannel().postMessage({
|
|
49452
49446
|
type: 'pendo:sr:refresh'
|
|
49453
49447
|
});
|
|
49454
|
-
}
|
|
49455
|
-
|
|
49456
|
-
|
|
49448
|
+
}
|
|
49449
|
+
_frameMessage(e) {
|
|
49450
|
+
const message = e.data;
|
|
49457
49451
|
if (message.type === 'pendo:sr:id') {
|
|
49458
49452
|
// When useBroadcastChannel is true, code in filterCrossWindowMessages restricts messages to frames in the
|
|
49459
49453
|
// current browser window/tab. Due to a race condition in clone-detection, you can have two tabs that
|
|
@@ -49469,18 +49463,17 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49469
49463
|
else if (message.type === 'pendo:sr:refresh' && window == window.top) {
|
|
49470
49464
|
this._sendIds();
|
|
49471
49465
|
}
|
|
49472
|
-
}
|
|
49473
|
-
|
|
49466
|
+
}
|
|
49467
|
+
clearSessionId() {
|
|
49474
49468
|
delete this._sessionId;
|
|
49475
49469
|
this.api.sessionStorage.removeItem(SESSION_RECORDING_ID);
|
|
49476
49470
|
this.api.sessionStorage.removeItem(this.sessionIdKey);
|
|
49477
|
-
}
|
|
49478
|
-
|
|
49479
|
-
if (defaultId === void 0) { defaultId = this.pendo.randomString(16); }
|
|
49471
|
+
}
|
|
49472
|
+
sessionId(defaultId = this.pendo.randomString(16)) {
|
|
49480
49473
|
if (!this._sessionId) {
|
|
49481
|
-
|
|
49474
|
+
let currentSessionId = this.api.sessionStorage.getItem(this.sessionIdKey);
|
|
49482
49475
|
if (!currentSessionId) {
|
|
49483
|
-
|
|
49476
|
+
let legacySessionId = this.api.sessionStorage.getItem(SESSION_RECORDING_ID);
|
|
49484
49477
|
if (legacySessionId) {
|
|
49485
49478
|
currentSessionId = legacySessionId;
|
|
49486
49479
|
this.api.sessionStorage.removeItem(SESSION_RECORDING_ID);
|
|
@@ -49493,41 +49486,41 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49493
49486
|
this._sessionId = currentSessionId;
|
|
49494
49487
|
}
|
|
49495
49488
|
return this._sessionId;
|
|
49496
|
-
}
|
|
49497
|
-
|
|
49498
|
-
|
|
49489
|
+
}
|
|
49490
|
+
clearOldSessionId() {
|
|
49491
|
+
let lastUserInteractionEventInfo = this.getLastUserInteractionEventInformation();
|
|
49499
49492
|
if (lastUserInteractionEventInfo) {
|
|
49500
|
-
|
|
49501
|
-
|
|
49502
|
-
|
|
49493
|
+
const lastEmitTime = lastUserInteractionEventInfo.timestamp;
|
|
49494
|
+
const sameVisitor = lastUserInteractionEventInfo.visitorId === this.visitorId && lastUserInteractionEventInfo.accountId === this.accountId;
|
|
49495
|
+
const withinInactivityLimit = lastEmitTime > Date.now() - this.pendo._.get(this.visitorConfig, 'inactivityDuration', THIRTY_MINUTES);
|
|
49503
49496
|
if (sameVisitor && withinInactivityLimit)
|
|
49504
49497
|
return;
|
|
49505
49498
|
}
|
|
49506
49499
|
this.clearSessionInfo();
|
|
49507
49500
|
this.isNewSession = true;
|
|
49508
|
-
}
|
|
49509
|
-
|
|
49501
|
+
}
|
|
49502
|
+
clearSessionInfo() {
|
|
49510
49503
|
this.currentRecordingSize = 0;
|
|
49511
49504
|
this.clearSessionId();
|
|
49512
49505
|
this.clearLastUserInteractionEventInformation();
|
|
49513
|
-
}
|
|
49514
|
-
|
|
49506
|
+
}
|
|
49507
|
+
isUserInteraction(event) {
|
|
49515
49508
|
if (event.type !== EVENT_TYPES.INCREMENTAL_SNAPSHOT) {
|
|
49516
49509
|
return false;
|
|
49517
49510
|
}
|
|
49518
49511
|
return event.data.source > EVENT_TYPES.INCREMENTAL_SOURCE_MUTATION && event.data.source <= EVENT_TYPES.INCREMENTAL_SOURCE_INPUT;
|
|
49519
|
-
}
|
|
49520
|
-
|
|
49512
|
+
}
|
|
49513
|
+
storeLastUserInteractionEventInformation(event, visitorId, accountId, skipUserInteractionCheck) {
|
|
49521
49514
|
if (this.isUserInteraction(event) || skipUserInteractionCheck) {
|
|
49522
|
-
this.lastUserInteractionEventInfo = { timestamp: event.timestamp, visitorId
|
|
49515
|
+
this.lastUserInteractionEventInfo = { timestamp: event.timestamp, visitorId, accountId };
|
|
49523
49516
|
this.api.sessionStorage.setItem(SESSION_RECORDING_LAST_USER_INTERACTION_EVENT, JSON.stringify(this.lastUserInteractionEventInfo));
|
|
49524
49517
|
}
|
|
49525
|
-
}
|
|
49526
|
-
|
|
49518
|
+
}
|
|
49519
|
+
clearLastUserInteractionEventInformation() {
|
|
49527
49520
|
delete this.lastUserInteractionEventInfo;
|
|
49528
49521
|
this.api.sessionStorage.removeItem(SESSION_RECORDING_LAST_USER_INTERACTION_EVENT);
|
|
49529
|
-
}
|
|
49530
|
-
|
|
49522
|
+
}
|
|
49523
|
+
getLastUserInteractionEventInformation() {
|
|
49531
49524
|
if (this.lastUserInteractionEventInfo)
|
|
49532
49525
|
return this.lastUserInteractionEventInfo;
|
|
49533
49526
|
try {
|
|
@@ -49537,7 +49530,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49537
49530
|
catch (e) { // nothing here yet or failed to be written; don't need to log
|
|
49538
49531
|
return null;
|
|
49539
49532
|
}
|
|
49540
|
-
}
|
|
49533
|
+
}
|
|
49541
49534
|
/**
|
|
49542
49535
|
* Handle new rrweb events coming in. This will also make sure that we are properly sending a "keyframe"
|
|
49543
49536
|
* as the BE expects it. A "keyframe" should consist of only the events needed to start a recording. This includes
|
|
@@ -49548,19 +49541,19 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49548
49541
|
* @param event.type The enum type of the specific event (e.g. meta, full snapshot, incremental snapshot)
|
|
49549
49542
|
* @param event.data The specific data to describe the event, this is different depending on what the type is
|
|
49550
49543
|
*/
|
|
49551
|
-
|
|
49552
|
-
|
|
49553
|
-
|
|
49554
|
-
|
|
49555
|
-
|
|
49556
|
-
|
|
49544
|
+
emit(event) {
|
|
49545
|
+
const isMeta = event.type === EVENT_TYPES.META;
|
|
49546
|
+
const isSnapshot = event.type === EVENT_TYPES.FULL_SNAPSHOT;
|
|
49547
|
+
const prevLastEmitTime = this.pendo._.get(this.getLastUserInteractionEventInformation(), 'timestamp');
|
|
49548
|
+
const inactivityDuration = this.pendo._.get(this.visitorConfig, 'inactivityDuration', THIRTY_MINUTES);
|
|
49549
|
+
let skipUserInteractionCheck = false;
|
|
49557
49550
|
if (event.timestamp && event.timestamp.getTime) {
|
|
49558
49551
|
event.timestamp = event.timestamp.getTime();
|
|
49559
49552
|
}
|
|
49560
49553
|
if (!event.timestamp) {
|
|
49561
49554
|
event.timestamp = (new Date()).getTime();
|
|
49562
49555
|
}
|
|
49563
|
-
|
|
49556
|
+
const withinInactivityLimit = prevLastEmitTime && event.timestamp - prevLastEmitTime <= inactivityDuration;
|
|
49564
49557
|
// If we don't have a last emit time and a META event is emitted, store the META event as the last user interaction
|
|
49565
49558
|
// event. This most commonly happens when a replay is first started and establishes a baseline timestamp to
|
|
49566
49559
|
// to compare inactivity against. For subsequent META events that are part of the same replay, we should have
|
|
@@ -49583,7 +49576,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49583
49576
|
this.logStopReason('INACTIVE_HIDDEN_TAB');
|
|
49584
49577
|
}
|
|
49585
49578
|
if (!this.isCheckingVisitorEligibility) {
|
|
49586
|
-
|
|
49579
|
+
const continuationCallback = function () {
|
|
49587
49580
|
this.send();
|
|
49588
49581
|
this.clearSessionInfo();
|
|
49589
49582
|
this.snapshot();
|
|
@@ -49619,13 +49612,13 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49619
49612
|
}
|
|
49620
49613
|
else if (!isMeta) {
|
|
49621
49614
|
this.eventsSinceLastKeyFrame += 1;
|
|
49622
|
-
|
|
49623
|
-
|
|
49624
|
-
|
|
49625
|
-
|
|
49626
|
-
|
|
49615
|
+
const timeSinceLastKeyFrame = event.timestamp - this.lastKeyFrameTime;
|
|
49616
|
+
const exceeds24Hours = timeSinceLastKeyFrame >= ONE_DAY_IN_MILLISECONDS;
|
|
49617
|
+
const exceedsTimeFreq = timeSinceLastKeyFrame >= this.pendo._.get(this.visitorConfig, 'keyframeTimeFrequency', 30645047); // Defaults determined by BE originally, shouldn't really ever be used
|
|
49618
|
+
const exceedsEventFreq = this.eventsSinceLastKeyFrame >= this.pendo._.get(this.visitorConfig, 'keyframeEventFrequency', 4548); // Defaults determined by BE originally, shouldn't really ever be used
|
|
49619
|
+
const exceedsRecordingSizeLimit = this.currentRecordingSize >= this.pendo._.get(this.visitorConfig, 'recordingSizeLimit', ONE_HUNDRED_MB_IN_BYTES);
|
|
49627
49620
|
if (exceeds24Hours || (exceedsTimeFreq && exceedsEventFreq) || exceedsRecordingSizeLimit) {
|
|
49628
|
-
|
|
49621
|
+
const continuationCallback = function () {
|
|
49629
49622
|
this.currentRecordingSize = 0;
|
|
49630
49623
|
this.snapshot();
|
|
49631
49624
|
};
|
|
@@ -49637,18 +49630,18 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49637
49630
|
}
|
|
49638
49631
|
}
|
|
49639
49632
|
}
|
|
49640
|
-
}
|
|
49641
|
-
|
|
49633
|
+
}
|
|
49634
|
+
updateCurrentRecordingSize(recordingPayloadSize) {
|
|
49642
49635
|
this.currentRecordingSize += recordingPayloadSize;
|
|
49643
|
-
}
|
|
49644
|
-
|
|
49636
|
+
}
|
|
49637
|
+
onWorkerMessage(messageData) {
|
|
49645
49638
|
switch (messageData.type) {
|
|
49646
49639
|
case 'workerDied': {
|
|
49647
49640
|
this.logStopReason('WORKER_DIED');
|
|
49648
49641
|
break;
|
|
49649
49642
|
}
|
|
49650
49643
|
case 'recordingPayloadSize': {
|
|
49651
|
-
|
|
49644
|
+
const { recordingPayloadSize, exceedsPayloadSizeLimit } = messageData;
|
|
49652
49645
|
if (!recordingPayloadSize)
|
|
49653
49646
|
return;
|
|
49654
49647
|
// stop recording if recording payload exceeds allowed payload size
|
|
@@ -49661,7 +49654,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49661
49654
|
break;
|
|
49662
49655
|
}
|
|
49663
49656
|
case 'hostedResources': {
|
|
49664
|
-
|
|
49657
|
+
const { hostedResourcesEvent } = messageData;
|
|
49665
49658
|
if (!hostedResourcesEvent)
|
|
49666
49659
|
return;
|
|
49667
49660
|
this.sendHostedResources(hostedResourcesEvent);
|
|
@@ -49672,12 +49665,12 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49672
49665
|
break;
|
|
49673
49666
|
}
|
|
49674
49667
|
case 'missingData': {
|
|
49675
|
-
this.logStopReason(
|
|
49668
|
+
this.logStopReason(`MISSING_${messageData.missingData}`);
|
|
49676
49669
|
break;
|
|
49677
49670
|
}
|
|
49678
49671
|
}
|
|
49679
|
-
}
|
|
49680
|
-
|
|
49672
|
+
}
|
|
49673
|
+
addRecordingId(event) {
|
|
49681
49674
|
if (!this.isRecording())
|
|
49682
49675
|
return;
|
|
49683
49676
|
if (!this.recordingId || !event || !event.data || !event.data.length)
|
|
@@ -49696,7 +49689,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49696
49689
|
return;
|
|
49697
49690
|
}
|
|
49698
49691
|
this._markEvents([capturedEvent]);
|
|
49699
|
-
}
|
|
49692
|
+
}
|
|
49700
49693
|
/**
|
|
49701
49694
|
* Used to stop collecting replay data.
|
|
49702
49695
|
*
|
|
@@ -49707,7 +49700,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49707
49700
|
* @example
|
|
49708
49701
|
* pendo.recording.stop()
|
|
49709
49702
|
*/
|
|
49710
|
-
|
|
49703
|
+
stop() {
|
|
49711
49704
|
if (this._stop) {
|
|
49712
49705
|
this._stop();
|
|
49713
49706
|
}
|
|
@@ -49725,33 +49718,32 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49725
49718
|
this.accountId = null;
|
|
49726
49719
|
this.clearSessionInfo();
|
|
49727
49720
|
this.onRecordingStop();
|
|
49728
|
-
}
|
|
49729
|
-
|
|
49721
|
+
}
|
|
49722
|
+
handleHidden() {
|
|
49730
49723
|
this.send({ hidden: true });
|
|
49731
|
-
}
|
|
49732
|
-
|
|
49724
|
+
}
|
|
49725
|
+
handleUnload() {
|
|
49733
49726
|
if (this.api.ConfigReader.get(RECORDING_CONFIG_DISABLE_UNLOAD))
|
|
49734
49727
|
return;
|
|
49735
49728
|
this.send({ unload: true });
|
|
49736
|
-
}
|
|
49737
|
-
|
|
49729
|
+
}
|
|
49730
|
+
buildRequestUrl(baseUrl, queryObj) {
|
|
49738
49731
|
var authedQueryObj = this.pendo._.extend({}, this.api.agent.getJwtInfoCopy(), queryObj);
|
|
49739
49732
|
var queryString = this.pendo._.map(authedQueryObj, function (value, key) {
|
|
49740
|
-
return
|
|
49733
|
+
return `${key}=${value}`;
|
|
49741
49734
|
}).join('&');
|
|
49742
|
-
return queryString.length ?
|
|
49743
|
-
}
|
|
49744
|
-
|
|
49735
|
+
return queryString.length ? `${baseUrl}?${queryString}` : baseUrl;
|
|
49736
|
+
}
|
|
49737
|
+
sendFailure(reason) {
|
|
49745
49738
|
this.stop();
|
|
49746
49739
|
this.logStopReason(reason);
|
|
49747
|
-
}
|
|
49748
|
-
|
|
49740
|
+
}
|
|
49741
|
+
rateLimitExceeded() {
|
|
49749
49742
|
this.send(); // sends first chunk of 20k
|
|
49750
49743
|
this.stop(); // sends 2nd chunk of 20k, rest is ignored
|
|
49751
49744
|
this.logStopReason('DATA_OVERLOAD');
|
|
49752
|
-
}
|
|
49753
|
-
|
|
49754
|
-
var _b = _a === void 0 ? {} : _a, _c = _b.unload, unload = _c === void 0 ? false : _c, _d = _b.keyframe, keyframe = _d === void 0 ? false : _d, _e = _b.hidden, hidden = _e === void 0 ? false : _e;
|
|
49745
|
+
}
|
|
49746
|
+
send({ unload = false, keyframe = false, hidden = false } = {}) {
|
|
49755
49747
|
if (!this.isRecording())
|
|
49756
49748
|
return;
|
|
49757
49749
|
if (!this.buffer)
|
|
@@ -49781,7 +49773,7 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49781
49773
|
}
|
|
49782
49774
|
// Used to add promoted metadata onto the recording event
|
|
49783
49775
|
this.api.Events.eventCaptured.trigger(payload);
|
|
49784
|
-
|
|
49776
|
+
const params = {
|
|
49785
49777
|
v: this.pendo.VERSION,
|
|
49786
49778
|
recordingId: this.recordingId
|
|
49787
49779
|
};
|
|
@@ -49792,11 +49784,11 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49792
49784
|
params.ns = 1;
|
|
49793
49785
|
this.isNewSession = false;
|
|
49794
49786
|
}
|
|
49795
|
-
var url = this.buildRequestUrl(
|
|
49787
|
+
var url = this.buildRequestUrl(`${this.pendo.HOST}/data/rec/${this.pendo.apiKey}`, params);
|
|
49796
49788
|
payload = this.buffer.pack(payload, this.pendo._);
|
|
49797
49789
|
if (unload || hidden) {
|
|
49798
49790
|
try {
|
|
49799
|
-
this.sendQueue.drain([{ url
|
|
49791
|
+
this.sendQueue.drain([{ url, payload }], unload);
|
|
49800
49792
|
}
|
|
49801
49793
|
catch (e) {
|
|
49802
49794
|
if (e.reason) {
|
|
@@ -49808,30 +49800,29 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49808
49800
|
}
|
|
49809
49801
|
}
|
|
49810
49802
|
else {
|
|
49811
|
-
this.sendQueue.push({ url
|
|
49803
|
+
this.sendQueue.push({ url, payload });
|
|
49812
49804
|
}
|
|
49813
49805
|
if (!this.buffer.isEmpty()) {
|
|
49814
|
-
this.send({ unload
|
|
49806
|
+
this.send({ unload });
|
|
49815
49807
|
}
|
|
49816
|
-
}
|
|
49817
|
-
|
|
49818
|
-
|
|
49808
|
+
}
|
|
49809
|
+
fetchVisitorConfig() {
|
|
49810
|
+
const jzb = this.pendo.compress({
|
|
49819
49811
|
url: this.pendo.url.get(),
|
|
49820
49812
|
metadata: this.pendo.getSerializedMetadata(),
|
|
49821
49813
|
visitorId: this.visitorId,
|
|
49822
49814
|
accountId: this.accountId
|
|
49823
49815
|
});
|
|
49824
|
-
|
|
49825
|
-
jzb
|
|
49816
|
+
const url = this.buildRequestUrl(`${this.pendo.HOST}/data/recordingconf/${this.pendo.apiKey}`, {
|
|
49817
|
+
jzb,
|
|
49826
49818
|
ct: (new Date().getTime()),
|
|
49827
49819
|
v: this.pendo.VERSION
|
|
49828
49820
|
});
|
|
49829
49821
|
return fetch(url, {
|
|
49830
49822
|
method: 'GET'
|
|
49831
|
-
}).then(
|
|
49832
|
-
}
|
|
49833
|
-
|
|
49834
|
-
var _this = this;
|
|
49823
|
+
}).then(response => response.json());
|
|
49824
|
+
}
|
|
49825
|
+
logStopReason(reason, error) {
|
|
49835
49826
|
var tracer = this.api.EventTracer.addTracerIds({});
|
|
49836
49827
|
var payload = this.pendo._.extend({
|
|
49837
49828
|
type: 'recording',
|
|
@@ -49847,53 +49838,51 @@ var SessionRecorder = /** @class */ (function () {
|
|
|
49847
49838
|
recordingPayload: [],
|
|
49848
49839
|
sequence: 0,
|
|
49849
49840
|
recordingPayloadCount: 0,
|
|
49850
|
-
props:
|
|
49841
|
+
props: Object.assign({ reason }, (error && { error: error instanceof Error ? error === null || error === void 0 ? void 0 : error.message : error }))
|
|
49851
49842
|
}, tracer);
|
|
49852
49843
|
var jzb = this.pendo.compress(payload);
|
|
49853
|
-
var url = this.buildRequestUrl(
|
|
49854
|
-
jzb
|
|
49844
|
+
var url = this.buildRequestUrl(`${this.pendo.HOST}/data/rec/${this.pendo.apiKey}`, {
|
|
49845
|
+
jzb,
|
|
49855
49846
|
ct: (new Date().getTime()),
|
|
49856
49847
|
v: this.pendo.VERSION,
|
|
49857
49848
|
recordingId: payload.recordingId
|
|
49858
49849
|
});
|
|
49859
49850
|
var body = this.pendo.compress(payload, 'binary');
|
|
49860
49851
|
return this.transport.post(url, {
|
|
49861
|
-
body
|
|
49852
|
+
body,
|
|
49862
49853
|
keepalive: true
|
|
49863
|
-
})
|
|
49864
|
-
|
|
49854
|
+
}).catch((e) => {
|
|
49855
|
+
this.api.log.critical('Failed to send reason for stopping recording', { error: e });
|
|
49865
49856
|
});
|
|
49866
|
-
}
|
|
49867
|
-
|
|
49868
|
-
var _this = this;
|
|
49857
|
+
}
|
|
49858
|
+
sendHostedResources(event) {
|
|
49869
49859
|
var tracer = this.api.EventTracer.addTracerIds({});
|
|
49870
|
-
var payload = this.pendo._.extend(
|
|
49871
|
-
var url = this.buildRequestUrl(
|
|
49860
|
+
var payload = this.pendo._.extend(Object.assign(Object.assign({}, event), { browserTime: new Date().getTime() }), tracer);
|
|
49861
|
+
var url = this.buildRequestUrl(`${this.pendo.HOST}/data/rec/${this.pendo.apiKey}`, {
|
|
49872
49862
|
ct: (new Date().getTime()),
|
|
49873
49863
|
v: this.pendo.VERSION,
|
|
49874
49864
|
recordingId: payload.recordingId
|
|
49875
49865
|
});
|
|
49876
49866
|
var body = this.pendo.compress(payload, 'binary');
|
|
49877
49867
|
return this.transport.post(url, {
|
|
49878
|
-
body
|
|
49868
|
+
body,
|
|
49879
49869
|
keepalive: true
|
|
49880
|
-
})
|
|
49881
|
-
|
|
49870
|
+
}).catch((e) => {
|
|
49871
|
+
this.api.log.critical('Failed to send hosted resources for recording event', { error: e });
|
|
49882
49872
|
});
|
|
49883
|
-
}
|
|
49873
|
+
}
|
|
49884
49874
|
/**
|
|
49885
49875
|
* This should fire when an event is triggered in clearClonedStorage. Under normal circumstances, the event will be
|
|
49886
49876
|
* triggered before recording begins in the cloned tab. On the off chance tabId changes again though, create a new
|
|
49887
49877
|
* replay. We want to avoid scenarios where a single recordingId is associated with multiple tabIds. This can happen if
|
|
49888
49878
|
* clone detection runs in a duplicated tab before it runs in the original tab.
|
|
49889
49879
|
*/
|
|
49890
|
-
|
|
49880
|
+
handleTabIdChange() {
|
|
49891
49881
|
this.send();
|
|
49892
49882
|
this.clearSessionInfo();
|
|
49893
49883
|
this.snapshot();
|
|
49894
|
-
}
|
|
49895
|
-
|
|
49896
|
-
}());
|
|
49884
|
+
}
|
|
49885
|
+
}
|
|
49897
49886
|
|
|
49898
49887
|
function wrapMethodWithCatch(method) {
|
|
49899
49888
|
return function () {
|
|
@@ -49914,8 +49903,7 @@ function errorLogger(recorder) {
|
|
|
49914
49903
|
return recorder;
|
|
49915
49904
|
if (!recorder.constructor || !recorder.constructor.prototype)
|
|
49916
49905
|
return recorder;
|
|
49917
|
-
for (
|
|
49918
|
-
var methodName = _a[_i];
|
|
49906
|
+
for (let methodName of Object.getOwnPropertyNames(recorder.constructor.prototype)) {
|
|
49919
49907
|
if (methodName === 'constructor')
|
|
49920
49908
|
continue;
|
|
49921
49909
|
recorder[methodName] = wrapMethodWithCatch(recorder[methodName]);
|
|
@@ -51537,59 +51525,59 @@ function ConsoleCapture() {
|
|
|
51537
51525
|
}
|
|
51538
51526
|
|
|
51539
51527
|
function NetworkCapture() {
|
|
51540
|
-
|
|
51541
|
-
|
|
51542
|
-
|
|
51543
|
-
|
|
51544
|
-
|
|
51545
|
-
|
|
51546
|
-
|
|
51547
|
-
|
|
51548
|
-
|
|
51549
|
-
|
|
51550
|
-
|
|
51551
|
-
|
|
51552
|
-
|
|
51553
|
-
|
|
51554
|
-
|
|
51555
|
-
|
|
51556
|
-
|
|
51557
|
-
|
|
51558
|
-
|
|
51559
|
-
|
|
51560
|
-
|
|
51561
|
-
|
|
51528
|
+
let pluginAPI;
|
|
51529
|
+
let globalPendo;
|
|
51530
|
+
let requestMap = {};
|
|
51531
|
+
let buffer;
|
|
51532
|
+
let sendQueue;
|
|
51533
|
+
let sendInterval;
|
|
51534
|
+
let transport;
|
|
51535
|
+
let isPtmPaused;
|
|
51536
|
+
let requestBodyCb;
|
|
51537
|
+
let responseBodyCb;
|
|
51538
|
+
let pendoDevlogBaseUrl;
|
|
51539
|
+
let isCapturingNetworkLogs = false;
|
|
51540
|
+
let excludeRequestUrls = [];
|
|
51541
|
+
const CAPTURE_NETWORK_CONFIG = 'captureNetworkRequests';
|
|
51542
|
+
const NETWORK_SUB_TYPE = 'network';
|
|
51543
|
+
const NETWORK_LOGS_CONFIG = 'networkLogs';
|
|
51544
|
+
const NETWORK_LOGS_CONFIG_ALLOWED_REQUEST_HEADERS = 'networkLogs.allowedRequestHeaders';
|
|
51545
|
+
const NETWORK_LOGS_CONFIG_ALLOWED_RESPONSE_HEADERS = 'networkLogs.allowedResponseHeaders';
|
|
51546
|
+
const NETWORK_LOGS_CONFIG_CAPTURE_REQUEST_BODY = 'networkLogs.captureRequestBody';
|
|
51547
|
+
const NETWORK_LOGS_CONFIG_CAPTURE_RESPONSE_BODY = 'networkLogs.captureResponseBody';
|
|
51548
|
+
const NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS = 'networkLogs.excludeRequestUrls';
|
|
51549
|
+
const allowedRequestHeaders = {
|
|
51562
51550
|
'content-type': true, 'content-length': true, 'accept': true, 'accept-language': true
|
|
51563
51551
|
};
|
|
51564
|
-
|
|
51552
|
+
const allowedResponseHeaders = {
|
|
51565
51553
|
'cache-control': true, 'content-length': true, 'content-type': true, 'content-language': true
|
|
51566
51554
|
};
|
|
51567
51555
|
return {
|
|
51568
51556
|
name: 'NetworkCapture',
|
|
51569
|
-
initialize
|
|
51570
|
-
teardown
|
|
51571
|
-
handleRequest
|
|
51572
|
-
handleResponse
|
|
51573
|
-
handleError
|
|
51574
|
-
startCapture
|
|
51575
|
-
createNetworkEvent
|
|
51576
|
-
send
|
|
51577
|
-
onPtmPaused
|
|
51578
|
-
onPtmUnpaused
|
|
51579
|
-
onAppHidden
|
|
51580
|
-
onAppUnloaded
|
|
51581
|
-
setCaptureState
|
|
51582
|
-
recordingStarted
|
|
51583
|
-
recordingStopped
|
|
51584
|
-
addConfigOptions
|
|
51585
|
-
processHeaderConfig
|
|
51586
|
-
extractHeaders
|
|
51587
|
-
setupBodyCallbacks
|
|
51588
|
-
processBody
|
|
51589
|
-
processRequestBody
|
|
51590
|
-
processResponseBody
|
|
51591
|
-
buildExcludeRequestUrls
|
|
51592
|
-
isUrlExcluded
|
|
51557
|
+
initialize,
|
|
51558
|
+
teardown,
|
|
51559
|
+
handleRequest,
|
|
51560
|
+
handleResponse,
|
|
51561
|
+
handleError,
|
|
51562
|
+
startCapture,
|
|
51563
|
+
createNetworkEvent,
|
|
51564
|
+
send,
|
|
51565
|
+
onPtmPaused,
|
|
51566
|
+
onPtmUnpaused,
|
|
51567
|
+
onAppHidden,
|
|
51568
|
+
onAppUnloaded,
|
|
51569
|
+
setCaptureState,
|
|
51570
|
+
recordingStarted,
|
|
51571
|
+
recordingStopped,
|
|
51572
|
+
addConfigOptions,
|
|
51573
|
+
processHeaderConfig,
|
|
51574
|
+
extractHeaders,
|
|
51575
|
+
setupBodyCallbacks,
|
|
51576
|
+
processBody,
|
|
51577
|
+
processRequestBody,
|
|
51578
|
+
processResponseBody,
|
|
51579
|
+
buildExcludeRequestUrls,
|
|
51580
|
+
isUrlExcluded,
|
|
51593
51581
|
get isCapturingNetworkLogs() {
|
|
51594
51582
|
return isCapturingNetworkLogs;
|
|
51595
51583
|
},
|
|
@@ -51624,9 +51612,9 @@ function NetworkCapture() {
|
|
|
51624
51612
|
function initialize(pendo, PluginAPI) {
|
|
51625
51613
|
pluginAPI = PluginAPI;
|
|
51626
51614
|
globalPendo = pendo;
|
|
51627
|
-
|
|
51615
|
+
const { ConfigReader } = pluginAPI;
|
|
51628
51616
|
ConfigReader.addOption(CAPTURE_NETWORK_CONFIG, [ConfigReader.sources.PENDO_CONFIG_SRC], false);
|
|
51629
|
-
|
|
51617
|
+
const captureNetworkEnabled = ConfigReader.get(CAPTURE_NETWORK_CONFIG);
|
|
51630
51618
|
if (!captureNetworkEnabled)
|
|
51631
51619
|
return;
|
|
51632
51620
|
buffer = new DevlogBuffer(pendo, pluginAPI);
|
|
@@ -51637,7 +51625,7 @@ function NetworkCapture() {
|
|
|
51637
51625
|
processHeaderConfig(NETWORK_LOGS_CONFIG_ALLOWED_RESPONSE_HEADERS, allowedResponseHeaders);
|
|
51638
51626
|
setupBodyCallbacks();
|
|
51639
51627
|
buildExcludeRequestUrls();
|
|
51640
|
-
sendInterval = setInterval(
|
|
51628
|
+
sendInterval = setInterval(() => {
|
|
51641
51629
|
if (!sendQueue.failed()) {
|
|
51642
51630
|
send();
|
|
51643
51631
|
}
|
|
@@ -51653,7 +51641,7 @@ function NetworkCapture() {
|
|
|
51653
51641
|
pendoDevlogBaseUrl = pluginAPI.transmit.buildBaseDataUrl(DEV_LOG_TYPE, globalPendo.apiKey);
|
|
51654
51642
|
}
|
|
51655
51643
|
function addConfigOptions() {
|
|
51656
|
-
|
|
51644
|
+
const { ConfigReader } = pluginAPI;
|
|
51657
51645
|
ConfigReader.addOption(NETWORK_LOGS_CONFIG, [ConfigReader.sources.SNIPPET_SRC], {});
|
|
51658
51646
|
/**
|
|
51659
51647
|
* Additional request headers to capture in network logs.
|
|
@@ -51712,17 +51700,17 @@ function NetworkCapture() {
|
|
|
51712
51700
|
ConfigReader.addOption(NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS, [ConfigReader.sources.SNIPPET_SRC], []);
|
|
51713
51701
|
}
|
|
51714
51702
|
function processHeaderConfig(configHeaderName, targetHeaders) {
|
|
51715
|
-
|
|
51703
|
+
const configHeaders = pluginAPI.ConfigReader.get(configHeaderName);
|
|
51716
51704
|
if (!configHeaders || configHeaders.length === 0)
|
|
51717
51705
|
return;
|
|
51718
|
-
globalPendo._.each(configHeaders,
|
|
51706
|
+
globalPendo._.each(configHeaders, (header) => {
|
|
51719
51707
|
if (!header || !globalPendo._.isString(header))
|
|
51720
51708
|
return;
|
|
51721
51709
|
targetHeaders[header.toLowerCase()] = true;
|
|
51722
51710
|
});
|
|
51723
51711
|
}
|
|
51724
51712
|
function setupBodyCallbacks() {
|
|
51725
|
-
|
|
51713
|
+
const config = pluginAPI.ConfigReader.get(NETWORK_LOGS_CONFIG);
|
|
51726
51714
|
if (!config)
|
|
51727
51715
|
return;
|
|
51728
51716
|
if (globalPendo._.isFunction(config.captureRequestBody)) {
|
|
@@ -51733,11 +51721,11 @@ function NetworkCapture() {
|
|
|
51733
51721
|
}
|
|
51734
51722
|
}
|
|
51735
51723
|
function buildExcludeRequestUrls() {
|
|
51736
|
-
|
|
51724
|
+
const requestUrls = pluginAPI.ConfigReader.get(NETWORK_LOGS_CONFIG_EXCLUDE_REQUEST_URLS);
|
|
51737
51725
|
if (!requestUrls || requestUrls.length === 0)
|
|
51738
51726
|
return;
|
|
51739
|
-
globalPendo._.each(requestUrls,
|
|
51740
|
-
|
|
51727
|
+
globalPendo._.each(requestUrls, (requestUrl) => {
|
|
51728
|
+
const processedRequestUrl = processUrlPattern(requestUrl);
|
|
51741
51729
|
if (!processedRequestUrl)
|
|
51742
51730
|
return;
|
|
51743
51731
|
excludeRequestUrls.push(processedRequestUrl);
|
|
@@ -51746,13 +51734,13 @@ function NetworkCapture() {
|
|
|
51746
51734
|
function processUrlPattern(url) {
|
|
51747
51735
|
if (!url)
|
|
51748
51736
|
return;
|
|
51749
|
-
|
|
51737
|
+
const isRegex = globalPendo._.isRegExp(url);
|
|
51750
51738
|
if (!globalPendo._.isString(url) && !isRegex)
|
|
51751
51739
|
return;
|
|
51752
51740
|
if (isRegex)
|
|
51753
51741
|
return url;
|
|
51754
|
-
|
|
51755
|
-
return new RegExp(
|
|
51742
|
+
const escapedUrl = pluginAPI.util.escapeRegExp(url);
|
|
51743
|
+
return new RegExp(`^${escapedUrl}$`);
|
|
51756
51744
|
}
|
|
51757
51745
|
function onPtmPaused() {
|
|
51758
51746
|
isPtmPaused = true;
|
|
@@ -51760,9 +51748,8 @@ function NetworkCapture() {
|
|
|
51760
51748
|
function onPtmUnpaused() {
|
|
51761
51749
|
isPtmPaused = false;
|
|
51762
51750
|
if (!buffer.isEmpty()) {
|
|
51763
|
-
for (
|
|
51764
|
-
|
|
51765
|
-
pluginAPI.Events.eventCaptured.trigger(event_1);
|
|
51751
|
+
for (const event of buffer.events) {
|
|
51752
|
+
pluginAPI.Events.eventCaptured.trigger(event);
|
|
51766
51753
|
}
|
|
51767
51754
|
send();
|
|
51768
51755
|
}
|
|
@@ -51773,12 +51760,11 @@ function NetworkCapture() {
|
|
|
51773
51760
|
function onAppUnloaded() {
|
|
51774
51761
|
send({ unload: true });
|
|
51775
51762
|
}
|
|
51776
|
-
function setCaptureState(
|
|
51777
|
-
var _b = _a === void 0 ? {} : _a, _c = _b.shouldCapture, shouldCapture = _c === void 0 ? false : _c, _d = _b.reason, reason = _d === void 0 ? '' : _d;
|
|
51763
|
+
function setCaptureState({ shouldCapture = false, reason = '' } = {}) {
|
|
51778
51764
|
if (shouldCapture === isCapturingNetworkLogs)
|
|
51779
51765
|
return;
|
|
51780
51766
|
isCapturingNetworkLogs = shouldCapture;
|
|
51781
|
-
pluginAPI.log.info(
|
|
51767
|
+
pluginAPI.log.info(`[NetworkCapture] Network request capture ${shouldCapture ? 'started' : 'stopped'}${reason ? `: ${reason}` : ''}`);
|
|
51782
51768
|
}
|
|
51783
51769
|
function recordingStarted() {
|
|
51784
51770
|
return setCaptureState({ shouldCapture: true, reason: 'recording started' });
|
|
@@ -51813,7 +51799,7 @@ function NetworkCapture() {
|
|
|
51813
51799
|
return false;
|
|
51814
51800
|
if (excludeRequestUrls.length === 0)
|
|
51815
51801
|
return false;
|
|
51816
|
-
return globalPendo._.some(excludeRequestUrls,
|
|
51802
|
+
return globalPendo._.some(excludeRequestUrls, (excludeRequestUrl) => {
|
|
51817
51803
|
return excludeRequestUrl.test(url);
|
|
51818
51804
|
});
|
|
51819
51805
|
}
|
|
@@ -51827,7 +51813,7 @@ function NetworkCapture() {
|
|
|
51827
51813
|
return;
|
|
51828
51814
|
if (!response)
|
|
51829
51815
|
return;
|
|
51830
|
-
|
|
51816
|
+
const request = requestMap[response.requestId];
|
|
51831
51817
|
if (!request)
|
|
51832
51818
|
return;
|
|
51833
51819
|
// Skip capturing successful devlog events to avoid infinite loops
|
|
@@ -51839,9 +51825,9 @@ function NetworkCapture() {
|
|
|
51839
51825
|
delete requestMap[response.requestId];
|
|
51840
51826
|
return;
|
|
51841
51827
|
}
|
|
51842
|
-
|
|
51843
|
-
request
|
|
51844
|
-
response
|
|
51828
|
+
const networkEvent = createNetworkEvent({
|
|
51829
|
+
request,
|
|
51830
|
+
response
|
|
51845
51831
|
});
|
|
51846
51832
|
if (!isPtmPaused) {
|
|
51847
51833
|
pluginAPI.Events.eventCaptured.trigger(networkEvent);
|
|
@@ -51849,8 +51835,7 @@ function NetworkCapture() {
|
|
|
51849
51835
|
buffer.push(networkEvent);
|
|
51850
51836
|
delete requestMap[response.requestId];
|
|
51851
51837
|
}
|
|
51852
|
-
function handleError(
|
|
51853
|
-
var error = _a.error, context = _a.context;
|
|
51838
|
+
function handleError({ error, context }) {
|
|
51854
51839
|
if (!isCapturingNetworkLogs)
|
|
51855
51840
|
return;
|
|
51856
51841
|
if (error.requestId && requestMap[error.requestId]) {
|
|
@@ -51864,13 +51849,13 @@ function NetworkCapture() {
|
|
|
51864
51849
|
}
|
|
51865
51850
|
}
|
|
51866
51851
|
function extractHeaders(headers, allowedHeaders) {
|
|
51867
|
-
|
|
51852
|
+
const { keys, reduce } = globalPendo._;
|
|
51868
51853
|
if (!headers || !allowedHeaders)
|
|
51869
51854
|
return [];
|
|
51870
|
-
return reduce(keys(headers),
|
|
51871
|
-
|
|
51855
|
+
return reduce(keys(headers), (acc, key) => {
|
|
51856
|
+
const normalizedKey = key.toLowerCase();
|
|
51872
51857
|
if (allowedHeaders[normalizedKey]) {
|
|
51873
|
-
acc.push(
|
|
51858
|
+
acc.push(`${key}: ${headers[key]}`);
|
|
51874
51859
|
}
|
|
51875
51860
|
return acc;
|
|
51876
51861
|
}, []);
|
|
@@ -51878,16 +51863,15 @@ function NetworkCapture() {
|
|
|
51878
51863
|
function processBody(body, contentType) {
|
|
51879
51864
|
if (!body || !globalPendo._.isString(body))
|
|
51880
51865
|
return '';
|
|
51881
|
-
|
|
51866
|
+
const processedBody = maskSensitiveFields({ string: body, contentType, _: globalPendo._ });
|
|
51882
51867
|
return truncate(processedBody, true);
|
|
51883
51868
|
}
|
|
51884
|
-
function processRequestBody(
|
|
51885
|
-
var request = _a.request;
|
|
51869
|
+
function processRequestBody({ request }) {
|
|
51886
51870
|
if (!request || !request.body || !requestBodyCb)
|
|
51887
51871
|
return '';
|
|
51888
51872
|
try {
|
|
51889
|
-
|
|
51890
|
-
|
|
51873
|
+
const body = requestBodyCb(request.body, { request });
|
|
51874
|
+
const contentType = globalPendo._.get(request, 'headers.content-type', '');
|
|
51891
51875
|
return processBody(body, contentType);
|
|
51892
51876
|
}
|
|
51893
51877
|
catch (error) {
|
|
@@ -51895,13 +51879,12 @@ function NetworkCapture() {
|
|
|
51895
51879
|
return '[Failed to process request body]';
|
|
51896
51880
|
}
|
|
51897
51881
|
}
|
|
51898
|
-
function processResponseBody(
|
|
51899
|
-
var response = _a.response;
|
|
51882
|
+
function processResponseBody({ response }) {
|
|
51900
51883
|
if (!response || !response.body || !responseBodyCb)
|
|
51901
51884
|
return '';
|
|
51902
51885
|
try {
|
|
51903
|
-
|
|
51904
|
-
|
|
51886
|
+
const body = responseBodyCb(response.body, { response });
|
|
51887
|
+
const contentType = globalPendo._.get(response, 'headers.content-type', '');
|
|
51905
51888
|
return processBody(body, contentType);
|
|
51906
51889
|
}
|
|
51907
51890
|
catch (error) {
|
|
@@ -51909,34 +51892,32 @@ function NetworkCapture() {
|
|
|
51909
51892
|
return '[Failed to process response body]';
|
|
51910
51893
|
}
|
|
51911
51894
|
}
|
|
51912
|
-
function createNetworkEvent(
|
|
51913
|
-
|
|
51914
|
-
|
|
51915
|
-
|
|
51916
|
-
|
|
51917
|
-
var networkEvent = __assign(__assign({}, devLogEnvelope), { subType: NETWORK_SUB_TYPE, devLogMethod: request.method, devLogStatusCode: response.status, devLogRequestUrl: request.url, devLogRequestHeaders: requestHeaders, devLogResponseHeaders: responseHeaders, devLogCount: 1 });
|
|
51895
|
+
function createNetworkEvent({ request, response }) {
|
|
51896
|
+
const devLogEnvelope = createDevLogEnvelope(pluginAPI, globalPendo);
|
|
51897
|
+
const requestHeaders = extractHeaders(request.headers, allowedRequestHeaders);
|
|
51898
|
+
const responseHeaders = extractHeaders(response.headers, allowedResponseHeaders);
|
|
51899
|
+
const networkEvent = Object.assign(Object.assign({}, devLogEnvelope), { subType: NETWORK_SUB_TYPE, devLogMethod: request.method, devLogStatusCode: response.status, devLogRequestUrl: request.url, devLogRequestHeaders: requestHeaders, devLogResponseHeaders: responseHeaders, devLogCount: 1 });
|
|
51918
51900
|
if (requestBodyCb) {
|
|
51919
|
-
networkEvent.devLogRequestBody = processRequestBody({ request
|
|
51901
|
+
networkEvent.devLogRequestBody = processRequestBody({ request });
|
|
51920
51902
|
}
|
|
51921
51903
|
if (responseBodyCb) {
|
|
51922
|
-
networkEvent.devLogResponseBody = processResponseBody({ response
|
|
51904
|
+
networkEvent.devLogResponseBody = processResponseBody({ response });
|
|
51923
51905
|
}
|
|
51924
51906
|
return networkEvent;
|
|
51925
51907
|
}
|
|
51926
|
-
function send(
|
|
51927
|
-
var _b = _a === void 0 ? {} : _a, _c = _b.unload, unload = _c === void 0 ? false : _c, _d = _b.hidden, hidden = _d === void 0 ? false : _d;
|
|
51908
|
+
function send({ unload = false, hidden = false } = {}) {
|
|
51928
51909
|
if (!buffer || buffer.isEmpty())
|
|
51929
51910
|
return;
|
|
51930
51911
|
if (!globalPendo.isSendingEvents()) {
|
|
51931
51912
|
buffer.clear();
|
|
51932
51913
|
return;
|
|
51933
51914
|
}
|
|
51934
|
-
|
|
51915
|
+
const payloads = buffer.pack();
|
|
51935
51916
|
if (unload || hidden) {
|
|
51936
51917
|
sendQueue.drain(payloads, unload);
|
|
51937
51918
|
}
|
|
51938
51919
|
else {
|
|
51939
|
-
sendQueue.push
|
|
51920
|
+
sendQueue.push(...payloads);
|
|
51940
51921
|
}
|
|
51941
51922
|
}
|
|
51942
51923
|
}
|
|
@@ -52270,13 +52251,13 @@ var predictGuidesScript = function (_a) {
|
|
|
52270
52251
|
cleanupArray.push(createFloatingModal({ recordId: recordId, configuration: configuration }));
|
|
52271
52252
|
};
|
|
52272
52253
|
|
|
52273
|
-
|
|
52274
|
-
|
|
52275
|
-
|
|
52276
|
-
|
|
52254
|
+
const PredictGuides = () => {
|
|
52255
|
+
let pluginApiRef = null;
|
|
52256
|
+
let cleanupArray = [];
|
|
52257
|
+
const cleanup = () => {
|
|
52277
52258
|
var _a;
|
|
52278
52259
|
(_a = pluginApiRef === null || pluginApiRef === void 0 ? void 0 : pluginApiRef.log) === null || _a === void 0 ? void 0 : _a.debug('[predict] cleaning up');
|
|
52279
|
-
for (
|
|
52260
|
+
for (let i = 0; i < cleanupArray.length; i++) {
|
|
52280
52261
|
try {
|
|
52281
52262
|
cleanupArray[i]();
|
|
52282
52263
|
}
|
|
@@ -52284,44 +52265,44 @@ var PredictGuides = function () {
|
|
|
52284
52265
|
}
|
|
52285
52266
|
cleanupArray = [];
|
|
52286
52267
|
};
|
|
52287
|
-
|
|
52268
|
+
const initialize = (_pendo, PluginAPI) => {
|
|
52288
52269
|
pluginApiRef = PluginAPI;
|
|
52289
|
-
|
|
52290
|
-
|
|
52270
|
+
const configReader = PluginAPI.ConfigReader;
|
|
52271
|
+
const PREDICT_GUIDES_CONFIG = 'predictGuides';
|
|
52291
52272
|
configReader.addOption(PREDICT_GUIDES_CONFIG, [
|
|
52292
52273
|
configReader.sources.SNIPPET_SRC,
|
|
52293
52274
|
configReader.sources.PENDO_CONFIG_SRC
|
|
52294
52275
|
], false);
|
|
52295
|
-
|
|
52276
|
+
const predictGuidesEnabled = configReader.get(PREDICT_GUIDES_CONFIG);
|
|
52296
52277
|
if (!predictGuidesEnabled)
|
|
52297
52278
|
return;
|
|
52298
|
-
|
|
52279
|
+
const log = PluginAPI.log.debug.bind(PluginAPI.log);
|
|
52299
52280
|
pluginApiRef.Events.urlChanged.on(cleanup);
|
|
52300
|
-
|
|
52281
|
+
const script = {
|
|
52301
52282
|
name: 'PredictFrameScript',
|
|
52302
|
-
script
|
|
52303
|
-
predictGuidesScript({ step
|
|
52304
|
-
this.on('unmounted',
|
|
52283
|
+
script(step, _guide, pendo) {
|
|
52284
|
+
predictGuidesScript({ step, pendo, cleanupArray, cleanup, log });
|
|
52285
|
+
this.on('unmounted', (evt) => {
|
|
52305
52286
|
if (evt.reason !== 'hidden')
|
|
52306
52287
|
cleanup();
|
|
52307
52288
|
});
|
|
52308
52289
|
},
|
|
52309
|
-
test
|
|
52310
|
-
|
|
52290
|
+
test(step, _guide) {
|
|
52291
|
+
const stepName = step.name || '';
|
|
52311
52292
|
return PREDICT_STEP_REGEX.test(stepName);
|
|
52312
52293
|
}
|
|
52313
52294
|
};
|
|
52314
52295
|
pluginApiRef.GlobalRuntime.addGlobalScript(script);
|
|
52315
52296
|
};
|
|
52316
|
-
|
|
52297
|
+
const teardown = () => {
|
|
52317
52298
|
var _a, _b;
|
|
52318
52299
|
cleanup();
|
|
52319
52300
|
(_b = (_a = pluginApiRef === null || pluginApiRef === void 0 ? void 0 : pluginApiRef.Events) === null || _a === void 0 ? void 0 : _a.urlChanged) === null || _b === void 0 ? void 0 : _b.off(cleanup);
|
|
52320
52301
|
};
|
|
52321
52302
|
return {
|
|
52322
52303
|
name: 'PredictGuides',
|
|
52323
|
-
initialize
|
|
52324
|
-
teardown
|
|
52304
|
+
initialize,
|
|
52305
|
+
teardown
|
|
52325
52306
|
};
|
|
52326
52307
|
};
|
|
52327
52308
|
|