@pendo/agent 2.300.1 → 2.301.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.
@@ -3540,7 +3540,6 @@ var ConfigReader = (function () {
3540
3540
  addOption('formValidation', [PENDO_CONFIG_SRC], false);
3541
3541
  // Performance Metrics
3542
3542
  addOption('performanceMetricsEnabled', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
3543
- addOption('sendPerformanceMetrics', [SNIPPET_SRC, PENDO_CONFIG_SRC], false);
3544
3543
  }
3545
3544
  initializeOptions();
3546
3545
  var sourceGetters = {};
@@ -3905,8 +3904,8 @@ let SERVER = '';
3905
3904
  let ASSET_HOST = '';
3906
3905
  let ASSET_PATH = '';
3907
3906
  let DESIGNER_SERVER = '';
3908
- let VERSION = '2.300.1_';
3909
- let PACKAGE_VERSION = '2.300.1';
3907
+ let VERSION = '2.301.1_';
3908
+ let PACKAGE_VERSION = '2.301.1';
3910
3909
  let LOADER = 'xhr';
3911
3910
  /* eslint-enable agent-eslint-rules/no-gulp-env-references */
3912
3911
  /**
@@ -5559,6 +5558,8 @@ var Events = (function () {
5559
5558
  new EventType('sessionChanged', [LIFECYCLE]),
5560
5559
  new EventType('ptm:unpaused', [LIFECYCLE]),
5561
5560
  new EventType('ptm:paused', [LIFECYCLE]),
5561
+ new EventType('recording:unpaused', [LIFECYCLE]),
5562
+ new EventType('recording:paused', [LIFECYCLE]),
5562
5563
  new EventType('childFrameJoined', [FRAMES]),
5563
5564
  new EventType('tabIdChanged:self', [DEBUG, LIFECYCLE])
5564
5565
  ];
@@ -6110,7 +6111,7 @@ var URL = (function(global, factory) {
6110
6111
  })(window, URLPolyfillFactory);
6111
6112
 
6112
6113
  function hasComposedPath(evt) {
6113
- return evt && _.isFunction(evt.composedPath);
6114
+ return evt && typeof evt.composedPath === 'function';
6114
6115
  }
6115
6116
  function getComposedPath(evt) {
6116
6117
  if (hasComposedPath(evt)) {
@@ -6262,6 +6263,7 @@ var sizzle = {exports: {}};
6262
6263
  tokenCache = createCache(),
6263
6264
  compilerCache = createCache(),
6264
6265
  nonnativeSelectorCache = createCache(),
6266
+ nativeishSelectorCache = createCache(),
6265
6267
  sortOrder = function( a, b ) {
6266
6268
  if ( a === b ) {
6267
6269
  hasDuplicate = true;
@@ -6455,6 +6457,46 @@ var sizzle = {exports: {}};
6455
6457
  };
6456
6458
  }
6457
6459
 
6460
+ function isContains(token) {
6461
+ return token.type === 'PSEUDO' && token.matches.length && token.matches[0].replace(rtrim, "$1").toLowerCase() === 'contains';
6462
+ }
6463
+
6464
+ function filterTokens(tokens, predicate) {
6465
+ if (tokens[0].length) {
6466
+ return tokens.map(function(innerTokens) {
6467
+ return filterTokens(innerTokens, predicate);
6468
+ });
6469
+ } else {
6470
+ return tokens.filter(predicate);
6471
+ }
6472
+ }
6473
+
6474
+ function tokensToSelector(tokens) {
6475
+ if (tokens[0].length) {
6476
+ return tokens.map(tokensToSelector).join(',');
6477
+ } else {
6478
+ return toSelector(tokens);
6479
+ }
6480
+ }
6481
+
6482
+ function findSeedForNonNativeSelector(selector, context, selectorCache) {
6483
+ var hopefullyNativeSelector = selectorCache[ selector + " " ];
6484
+ if (!hopefullyNativeSelector) {
6485
+ var nonnativeTokens = tokenize(selector);
6486
+ var hopefullyNativeTokens = filterTokens(nonnativeTokens, function(token) {
6487
+ return !isContains(token);
6488
+ });
6489
+ hopefullyNativeSelector = tokensToSelector(hopefullyNativeTokens);
6490
+ }
6491
+ try {
6492
+ var seed = [];
6493
+ push.apply(seed, context.querySelectorAll(hopefullyNativeSelector));
6494
+ selectorCache(selector, hopefullyNativeSelector);
6495
+ return seed;
6496
+ } catch (e) {
6497
+ }
6498
+ }
6499
+
6458
6500
  function Sizzle( selector, context, results, seed ) {
6459
6501
  var m, i, elem, nid, match, groups, newSelector,
6460
6502
  newContext = context && context.ownerDocument,
@@ -6531,7 +6573,7 @@ var sizzle = {exports: {}};
6531
6573
 
6532
6574
  // Take advantage of querySelectorAll
6533
6575
  if ( support.qsa &&
6534
- !nonnativeSelectorCache[ selector + " " ] &&
6576
+ (!nonnativeSelectorCache[ selector + " " ] || nativeishSelectorCache[ selector + " " ]) &&
6535
6577
  ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
6536
6578
 
6537
6579
  // Support: IE 8 only
@@ -6589,6 +6631,10 @@ var sizzle = {exports: {}};
6589
6631
  context.removeAttribute( "id" );
6590
6632
  }
6591
6633
  }
6634
+
6635
+ if (!seed && nonnativeSelectorCache[ selector + " " ]) {
6636
+ seed = findSeedForNonNativeSelector(selector, newContext, nativeishSelectorCache);
6637
+ }
6592
6638
  }
6593
6639
  }
6594
6640
  }
@@ -12364,8 +12410,6 @@ class PerformanceMonitor {
12364
12410
  return acc;
12365
12411
  }, []);
12366
12412
  this._clearMarksAndMeasures();
12367
- if (!ConfigReader.get('sendPerformanceMetrics'))
12368
- return;
12369
12413
  if (_.size(payload)) {
12370
12414
  writeMetricsPOST(payload);
12371
12415
  }
@@ -34259,11 +34303,11 @@ const NetworkUrlModule = (function (global) {
34259
34303
  const getters = {
34260
34304
  getTransformedUrl(state) {
34261
34305
  return function (url) {
34262
- if (_.size(state.transforms) < 1) {
34263
- return url;
34264
- }
34265
34306
  try {
34266
34307
  let urlObj = url instanceof URL ? url : new URL(url, window.location.origin);
34308
+ if (_.size(state.transforms) < 1) {
34309
+ return urlObj.href;
34310
+ }
34267
34311
  urlObj = applyTransforms(state.transforms, urlObj);
34268
34312
  return urlObj.href;
34269
34313
  }
@@ -48304,6 +48348,16 @@ class Transport {
48304
48348
  }
48305
48349
  }
48306
48350
 
48351
+ function isElementShadowRoot(elem, _win) {
48352
+ if (!_win) {
48353
+ _win = window;
48354
+ }
48355
+ return typeof _win.ShadowRoot !== 'undefined' && elem instanceof _win.ShadowRoot && elem.host;
48356
+ }
48357
+ function getParent(elem, _win) {
48358
+ return isElementShadowRoot(elem, _win) ? elem.host : elem.parentNode;
48359
+ }
48360
+
48307
48361
  const ELEMENT_NODE = 1;
48308
48362
  const INPUT_MASK = '*'.repeat(10);
48309
48363
  function isElementNode(node) {
@@ -48314,13 +48368,17 @@ function isElementNode(node) {
48314
48368
  return true;
48315
48369
  }
48316
48370
  function distanceToMatch(node, selector, limit = Infinity, distance = 0) {
48317
- if (!isElementNode(node))
48318
- return -1;
48319
48371
  if (distance > limit)
48320
48372
  return -1;
48321
- if (node.matches(selector))
48322
- return distance;
48323
- return distanceToMatch(node.parentNode, selector, limit, distance + 1);
48373
+ if (!node)
48374
+ return -1;
48375
+ if (isElementNode(node)) {
48376
+ if (node.matches(selector))
48377
+ return distance;
48378
+ if (node.parentNode)
48379
+ return distanceToMatch(node.parentNode, selector, limit, distance + 1);
48380
+ }
48381
+ return distanceToMatch(getParent(node), selector, limit, distance + 1);
48324
48382
  }
48325
48383
  function shouldMask(node, options) {
48326
48384
  const { maskAllText, maskTextSelector, unmaskTextSelector } = options;
@@ -50592,6 +50650,7 @@ var sizzle = {exports: {}};
50592
50650
  tokenCache = createCache(),
50593
50651
  compilerCache = createCache(),
50594
50652
  nonnativeSelectorCache = createCache(),
50653
+ nativeishSelectorCache = createCache(),
50595
50654
  sortOrder = function( a, b ) {
50596
50655
  if ( a === b ) {
50597
50656
  hasDuplicate = true;
@@ -50785,6 +50844,46 @@ var sizzle = {exports: {}};
50785
50844
  };
50786
50845
  }
50787
50846
 
50847
+ function isContains(token) {
50848
+ return token.type === 'PSEUDO' && token.matches.length && token.matches[0].replace(rtrim, "$1").toLowerCase() === 'contains';
50849
+ }
50850
+
50851
+ function filterTokens(tokens, predicate) {
50852
+ if (tokens[0].length) {
50853
+ return tokens.map(function(innerTokens) {
50854
+ return filterTokens(innerTokens, predicate);
50855
+ });
50856
+ } else {
50857
+ return tokens.filter(predicate);
50858
+ }
50859
+ }
50860
+
50861
+ function tokensToSelector(tokens) {
50862
+ if (tokens[0].length) {
50863
+ return tokens.map(tokensToSelector).join(',');
50864
+ } else {
50865
+ return toSelector(tokens);
50866
+ }
50867
+ }
50868
+
50869
+ function findSeedForNonNativeSelector(selector, context, selectorCache) {
50870
+ var hopefullyNativeSelector = selectorCache[ selector + " " ];
50871
+ if (!hopefullyNativeSelector) {
50872
+ var nonnativeTokens = tokenize(selector);
50873
+ var hopefullyNativeTokens = filterTokens(nonnativeTokens, function(token) {
50874
+ return !isContains(token);
50875
+ });
50876
+ hopefullyNativeSelector = tokensToSelector(hopefullyNativeTokens);
50877
+ }
50878
+ try {
50879
+ var seed = [];
50880
+ push.apply(seed, context.querySelectorAll(hopefullyNativeSelector));
50881
+ selectorCache(selector, hopefullyNativeSelector);
50882
+ return seed;
50883
+ } catch (e) {
50884
+ }
50885
+ }
50886
+
50788
50887
  function Sizzle( selector, context, results, seed ) {
50789
50888
  var m, i, elem, nid, match, groups, newSelector,
50790
50889
  newContext = context && context.ownerDocument,
@@ -50861,7 +50960,7 @@ var sizzle = {exports: {}};
50861
50960
 
50862
50961
  // Take advantage of querySelectorAll
50863
50962
  if ( support.qsa &&
50864
- !nonnativeSelectorCache[ selector + " " ] &&
50963
+ (!nonnativeSelectorCache[ selector + " " ] || nativeishSelectorCache[ selector + " " ]) &&
50865
50964
  ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
50866
50965
 
50867
50966
  // Support: IE 8 only
@@ -50919,6 +51018,10 @@ var sizzle = {exports: {}};
50919
51018
  context.removeAttribute( "id" );
50920
51019
  }
50921
51020
  }
51021
+
51022
+ if (!seed && nonnativeSelectorCache[ selector + " " ]) {
51023
+ seed = findSeedForNonNativeSelector(selector, newContext, nativeishSelectorCache);
51024
+ }
50922
51025
  }
50923
51026
  }
50924
51027
  }
@@ -53393,6 +53496,7 @@ class SessionRecorder {
53393
53496
  if (continuationCallback) {
53394
53497
  continuationCallback.call(this);
53395
53498
  }
53499
+ this.api.Events.trigger('recording:unpaused');
53396
53500
  }
53397
53501
  if (visitorConfig && visitorConfig.enable && !this.isRecording()) {
53398
53502
  this._startRecordingForVisitor(visitorConfig);
@@ -53501,6 +53605,7 @@ class SessionRecorder {
53501
53605
  });
53502
53606
  }
53503
53607
  _startRecordingForVisitor(visitorConfig) {
53608
+ this.api.Events.trigger('recording:unpaused');
53504
53609
  this.transport.start(this.config);
53505
53610
  const disableFallback = this.pendo._.get(this.config, 'disableFallback', true);
53506
53611
  if (disableFallback && !this.transport.worker) {
@@ -53819,6 +53924,7 @@ class SessionRecorder {
53819
53924
  this.interval = null;
53820
53925
  this._stop = null;
53821
53926
  this.visitorConfig = null;
53927
+ this.api.Events.trigger('recording:paused');
53822
53928
  this.visitorId = null;
53823
53929
  this.accountId = null;
53824
53930
  this.clearSessionInfo();
@@ -55200,21 +55306,35 @@ function createCspViolationMessage(blockedURI, directive, isReportOnly, original
55200
55306
  }
55201
55307
  }
55202
55308
 
55309
+ const DEV_LOG_TYPE = 'devlog';
55310
+ function createDevLogEnvelope(pluginAPI, globalPendo) {
55311
+ return {
55312
+ browser_time: pluginAPI.util.getNow(),
55313
+ url: globalPendo.url.get(),
55314
+ visitorId: globalPendo.get_visitor_id(),
55315
+ accountId: globalPendo.get_account_id(),
55316
+ type: DEV_LOG_TYPE
55317
+ };
55318
+ }
55319
+
55203
55320
  const TOKEN_MAX_SIZE = 100;
55204
55321
  const TOKEN_REFILL_RATE = 10;
55205
55322
  const TOKEN_REFRESH_INTERVAL = 1000;
55323
+ const MAX_UNCOMPRESSED_SIZE = 125000; // 125KB
55206
55324
  class DevlogBuffer {
55207
55325
  constructor(pendo, pluginAPI) {
55208
55326
  this.pendo = pendo;
55209
55327
  this.pluginAPI = pluginAPI;
55210
55328
  this.events = [];
55211
55329
  this.lastEvent = null;
55330
+ this.uncompressedSize = 0;
55331
+ this.payloads = [];
55212
55332
  this.tokens = TOKEN_MAX_SIZE;
55213
55333
  this.lastRefillTime = this.pluginAPI.util.getNow();
55214
55334
  this.nextRefillTime = this.lastRefillTime + TOKEN_REFRESH_INTERVAL;
55215
55335
  }
55216
55336
  isEmpty() {
55217
- return this.events.length === 0;
55337
+ return this.events.length === 0 && this.payloads.length === 0;
55218
55338
  }
55219
55339
  refillTokens() {
55220
55340
  const now = this.pluginAPI.util.getNow();
@@ -55230,22 +55350,53 @@ class DevlogBuffer {
55230
55350
  clear() {
55231
55351
  this.events = [];
55232
55352
  this.lastEvent = null;
55353
+ this.uncompressedSize = 0;
55233
55354
  }
55234
- push(event) {
55355
+ hasTokenAvailable() {
55235
55356
  this.refillTokens();
55236
- if (this.tokens === 0)
55357
+ return this.tokens > 0;
55358
+ }
55359
+ estimateEventSize(event) {
55360
+ return JSON.stringify(event).length;
55361
+ }
55362
+ push(event) {
55363
+ if (!this.hasTokenAvailable())
55237
55364
  return false;
55365
+ const eventSize = this.estimateEventSize(event);
55366
+ if (this.uncompressedSize + eventSize > MAX_UNCOMPRESSED_SIZE) {
55367
+ this.compressCurrentChunk();
55368
+ }
55369
+ this.uncompressedSize += eventSize;
55238
55370
  this.lastEvent = event;
55239
55371
  this.events.push(event);
55240
55372
  this.tokens = Math.max(this.tokens - 1, 0);
55241
55373
  return true;
55242
55374
  }
55243
- pack() {
55244
- if (this.isEmpty())
55375
+ compressCurrentChunk() {
55376
+ if (this.events.length === 0)
55245
55377
  return;
55246
55378
  const jzb = this.pendo.compress(this.events);
55379
+ this.payloads.push(jzb);
55247
55380
  this.clear();
55248
- return jzb;
55381
+ }
55382
+ generateUrl() {
55383
+ const queryParams = {
55384
+ v: this.pendo.VERSION,
55385
+ ct: this.pluginAPI.util.getNow()
55386
+ };
55387
+ return this.pluginAPI.transmit.buildBaseDataUrl(DEV_LOG_TYPE, this.pendo.apiKey, queryParams);
55388
+ }
55389
+ pack() {
55390
+ if (this.isEmpty())
55391
+ return;
55392
+ const url = this.generateUrl();
55393
+ this.compressCurrentChunk();
55394
+ const payloads = this.pendo._.map(this.payloads, (jzb) => ({
55395
+ jzb,
55396
+ url
55397
+ }));
55398
+ this.payloads = [];
55399
+ return payloads;
55249
55400
  }
55250
55401
  }
55251
55402
 
@@ -56437,7 +56588,6 @@ var ConfigReader = (function () {
56437
56588
  addOption('formValidation', [PENDO_CONFIG_SRC], false);
56438
56589
  // Performance Metrics
56439
56590
  addOption('performanceMetricsEnabled', [SNIPPET_SRC, PENDO_CONFIG_SRC], true);
56440
- addOption('sendPerformanceMetrics', [SNIPPET_SRC, PENDO_CONFIG_SRC], false);
56441
56591
  }
56442
56592
  initializeOptions();
56443
56593
  var sourceGetters = {};
@@ -57305,17 +57455,6 @@ class DevlogTransport {
57305
57455
  }
57306
57456
  }
57307
57457
 
57308
- const DEV_LOG_TYPE = 'devlog';
57309
- function createDevLogEnvelope(pluginAPI, globalPendo) {
57310
- return {
57311
- browser_time: pluginAPI.util.getNow(),
57312
- url: globalPendo.url.get(),
57313
- visitorId: globalPendo.get_visitor_id(),
57314
- accountId: globalPendo.get_account_id(),
57315
- type: DEV_LOG_TYPE
57316
- };
57317
- }
57318
-
57319
57458
  function ConsoleCapture() {
57320
57459
  let pluginAPI;
57321
57460
  let _;
@@ -57325,6 +57464,7 @@ function ConsoleCapture() {
57325
57464
  let sendInterval;
57326
57465
  let transport;
57327
57466
  let isPtmPaused;
57467
+ let isCapturingConsoleLogs = false;
57328
57468
  const CAPTURE_CONSOLE_CONFIG = 'captureConsoleLogs';
57329
57469
  const CONSOLE_METHODS = ['log', 'warn', 'error', 'info'];
57330
57470
  const DEV_LOG_SUB_TYPE = 'console';
@@ -57338,11 +57478,17 @@ function ConsoleCapture() {
57338
57478
  createConsoleEvent,
57339
57479
  captureStackTrace,
57340
57480
  send,
57481
+ setCaptureState,
57482
+ recordingStarted,
57483
+ recordingStopped,
57341
57484
  onAppHidden,
57342
57485
  onAppUnloaded,
57343
57486
  onPtmPaused,
57344
57487
  onPtmUnpaused,
57345
57488
  securityPolicyViolationFn,
57489
+ get isCapturingConsoleLogs() {
57490
+ return isCapturingConsoleLogs;
57491
+ },
57346
57492
  get buffer() {
57347
57493
  return buffer;
57348
57494
  },
@@ -57372,11 +57518,12 @@ function ConsoleCapture() {
57372
57518
  }, SEND_INTERVAL);
57373
57519
  sendQueue.start();
57374
57520
  pluginAPI.Events.ready.on(readyHandler);
57521
+ pluginAPI.Events['recording:unpaused'].on(recordingStarted);
57522
+ pluginAPI.Events['recording:paused'].on(recordingStopped);
57375
57523
  pluginAPI.Events.appUnloaded.on(onAppUnloaded);
57376
57524
  pluginAPI.Events.appHidden.on(onAppHidden);
57377
57525
  pluginAPI.Events['ptm:paused'].on(onPtmPaused);
57378
57526
  pluginAPI.Events['ptm:unpaused'].on(onPtmUnpaused);
57379
- pluginAPI.log.info('Console logs are being captured');
57380
57527
  }
57381
57528
  function onAppHidden() {
57382
57529
  send({ hidden: true });
@@ -57396,6 +57543,18 @@ function ConsoleCapture() {
57396
57543
  send();
57397
57544
  }
57398
57545
  }
57546
+ function setCaptureState({ shouldCapture = false, reason = '' } = {}) {
57547
+ if (shouldCapture === isCapturingConsoleLogs)
57548
+ return;
57549
+ isCapturingConsoleLogs = shouldCapture;
57550
+ pluginAPI.log.info(`[ConsoleCapture] Console log capture ${shouldCapture ? 'started' : 'stopped'}${reason ? `: ${reason}` : ''}`);
57551
+ }
57552
+ function recordingStarted() {
57553
+ setCaptureState({ shouldCapture: true, reason: 'recording started' });
57554
+ }
57555
+ function recordingStopped() {
57556
+ setCaptureState({ shouldCapture: false, reason: 'recording stopped' });
57557
+ }
57399
57558
  function readyHandler() {
57400
57559
  addIntercepts();
57401
57560
  pluginAPI.attachEventInternal(window, 'securitypolicyviolation', securityPolicyViolationFn);
@@ -57431,7 +57590,7 @@ function ConsoleCapture() {
57431
57590
  }
57432
57591
  }
57433
57592
  function createConsoleEvent(args, methodName, { skipStackTrace = false, skipScrubPII = false } = {}) {
57434
- if (!args || args.length === 0 || !_.contains(CONSOLE_METHODS, methodName))
57593
+ if (!isCapturingConsoleLogs || !args || args.length === 0 || !_.contains(CONSOLE_METHODS, methodName))
57435
57594
  return;
57436
57595
  // stringify args
57437
57596
  let message = _.compact(_.map(args, arg => {
@@ -57463,13 +57622,13 @@ function ConsoleCapture() {
57463
57622
  }
57464
57623
  const devLogEnvelope = createDevLogEnvelope(pluginAPI, globalPendo);
57465
57624
  const consoleEvent = Object.assign(Object.assign({}, devLogEnvelope), { subType: DEV_LOG_SUB_TYPE, devLogLevel: methodName === 'log' ? 'info' : methodName, devLogMessage: skipScrubPII ? message : scrubPII({ string: message, _ }), devLogTrace: stackTrace, devLogCount: 1 });
57466
- const wasAccepted = buffer.push(consoleEvent);
57467
- if (wasAccepted) {
57468
- if (!isPtmPaused) {
57469
- pluginAPI.Events.eventCaptured.trigger(consoleEvent);
57470
- }
57471
- updateLastLog(logKey);
57625
+ if (!buffer.hasTokenAvailable())
57626
+ return consoleEvent;
57627
+ if (!isPtmPaused) {
57628
+ pluginAPI.Events.eventCaptured.trigger(consoleEvent);
57472
57629
  }
57630
+ buffer.push(consoleEvent);
57631
+ updateLastLog(logKey);
57473
57632
  return consoleEvent;
57474
57633
  }
57475
57634
  function captureStackTrace(maxStackFrames) {
@@ -57494,19 +57653,14 @@ function ConsoleCapture() {
57494
57653
  buffer.clear();
57495
57654
  return;
57496
57655
  }
57497
- const queryParams = {
57498
- v: globalPendo.VERSION,
57499
- ct: pluginAPI.util.getNow()
57500
- };
57501
- const url = pluginAPI.transmit.buildBaseDataUrl(DEV_LOG_TYPE, globalPendo.apiKey, queryParams);
57502
- const jzb = buffer.pack();
57503
- if (!jzb)
57656
+ const payloads = buffer.pack();
57657
+ if (!payloads || payloads.length === 0)
57504
57658
  return;
57505
57659
  if (unload || hidden) {
57506
- sendQueue.drain([{ url, jzb }], unload);
57660
+ sendQueue.drain(payloads, unload);
57507
57661
  }
57508
57662
  else {
57509
- sendQueue.push({ url, jzb });
57663
+ sendQueue.push(...payloads);
57510
57664
  }
57511
57665
  }
57512
57666
  function teardown() {
@@ -57524,6 +57678,8 @@ function ConsoleCapture() {
57524
57678
  pluginAPI.Events.appUnloaded.off(onAppUnloaded);
57525
57679
  pluginAPI.Events['ptm:paused'].off(onPtmPaused);
57526
57680
  pluginAPI.Events['ptm:unpaused'].off(onPtmUnpaused);
57681
+ pluginAPI.Events['recording:unpaused'].off(recordingStarted);
57682
+ pluginAPI.Events['recording:paused'].off(recordingStopped);
57527
57683
  pluginAPI.detachEventInternal(window, 'securitypolicyviolation', securityPolicyViolationFn);
57528
57684
  _.each(CONSOLE_METHODS, function (methodName) {
57529
57685
  if (!console[methodName])
@@ -57548,6 +57704,7 @@ function NetworkCapture() {
57548
57704
  let requestBodyCb;
57549
57705
  let responseBodyCb;
57550
57706
  let pendoDevlogBaseUrl;
57707
+ let isCapturingNetworkLogs = false;
57551
57708
  const CAPTURE_NETWORK_CONFIG = 'captureNetworkRequests';
57552
57709
  const NETWORK_SUB_TYPE = 'network';
57553
57710
  const NETWORK_LOGS_CONFIG = 'networkLogs';
@@ -57575,6 +57732,9 @@ function NetworkCapture() {
57575
57732
  onPtmUnpaused,
57576
57733
  onAppHidden,
57577
57734
  onAppUnloaded,
57735
+ setCaptureState,
57736
+ recordingStarted,
57737
+ recordingStopped,
57578
57738
  addConfigOptions,
57579
57739
  processHeaderConfig,
57580
57740
  extractHeaders,
@@ -57582,6 +57742,9 @@ function NetworkCapture() {
57582
57742
  processBody,
57583
57743
  processRequestBody,
57584
57744
  processResponseBody,
57745
+ get isCapturingNetworkLogs() {
57746
+ return isCapturingNetworkLogs;
57747
+ },
57585
57748
  get requestMap() {
57586
57749
  return requestMap;
57587
57750
  },
@@ -57629,6 +57792,8 @@ function NetworkCapture() {
57629
57792
  }, SEND_INTERVAL);
57630
57793
  sendQueue.start();
57631
57794
  pluginAPI.Events.ready.on(startCapture);
57795
+ pluginAPI.Events['recording:unpaused'].on(recordingStarted);
57796
+ pluginAPI.Events['recording:paused'].on(recordingStopped);
57632
57797
  pluginAPI.Events['ptm:paused'].on(onPtmPaused);
57633
57798
  pluginAPI.Events['ptm:unpaused'].on(onPtmUnpaused);
57634
57799
  pluginAPI.Events.appHidden.on(onAppHidden);
@@ -57720,6 +57885,18 @@ function NetworkCapture() {
57720
57885
  function onAppUnloaded() {
57721
57886
  send({ unload: true });
57722
57887
  }
57888
+ function setCaptureState({ shouldCapture = false, reason = '' } = {}) {
57889
+ if (shouldCapture === isCapturingNetworkLogs)
57890
+ return;
57891
+ isCapturingNetworkLogs = shouldCapture;
57892
+ pluginAPI.log.info(`[NetworkCapture] Network request capture ${shouldCapture ? 'started' : 'stopped'}${reason ? `: ${reason}` : ''}`);
57893
+ }
57894
+ function recordingStarted() {
57895
+ return setCaptureState({ shouldCapture: true, reason: 'recording started' });
57896
+ }
57897
+ function recordingStopped() {
57898
+ return setCaptureState({ shouldCapture: false, reason: 'recording stopped' });
57899
+ }
57723
57900
  function startCapture() {
57724
57901
  pluginAPI.NetworkRequest.on({ request: handleRequest, response: handleResponse, error: handleError });
57725
57902
  }
@@ -57739,11 +57916,17 @@ function NetworkCapture() {
57739
57916
  pluginAPI.Events['ptm:unpaused'].off(onPtmUnpaused);
57740
57917
  pluginAPI.Events.appHidden.off(onAppHidden);
57741
57918
  pluginAPI.Events.appUnloaded.off(onAppUnloaded);
57919
+ pluginAPI.Events['recording:unpaused'].off(recordingStarted);
57920
+ pluginAPI.Events['recording:paused'].off(recordingStopped);
57742
57921
  }
57743
57922
  function handleRequest(request) {
57923
+ if (!isCapturingNetworkLogs)
57924
+ return;
57744
57925
  requestMap[request.requestId] = request;
57745
57926
  }
57746
57927
  function handleResponse(response) {
57928
+ if (!isCapturingNetworkLogs)
57929
+ return;
57747
57930
  if (!response)
57748
57931
  return;
57749
57932
  const request = requestMap[response.requestId];
@@ -57754,24 +57937,23 @@ function NetworkCapture() {
57754
57937
  delete requestMap[response.requestId];
57755
57938
  return;
57756
57939
  }
57757
- // push an empty network event to the buffer to ensure that we have a token available
57758
- const networkEvent = {};
57759
- const wasAccepted = buffer.push(networkEvent);
57760
- if (!wasAccepted) {
57761
- // Token limit reached, remove request from request map
57940
+ if (!buffer.hasTokenAvailable()) {
57762
57941
  delete requestMap[response.requestId];
57763
57942
  return;
57764
57943
  }
57765
- globalPendo._.extend(networkEvent, createNetworkEvent({
57944
+ const networkEvent = createNetworkEvent({
57766
57945
  request,
57767
57946
  response
57768
- }));
57947
+ });
57769
57948
  if (!isPtmPaused) {
57770
57949
  pluginAPI.Events.eventCaptured.trigger(networkEvent);
57771
57950
  }
57951
+ buffer.push(networkEvent);
57772
57952
  delete requestMap[response.requestId];
57773
57953
  }
57774
57954
  function handleError({ error, context }) {
57955
+ if (!isCapturingNetworkLogs)
57956
+ return;
57775
57957
  if (error.requestId && requestMap[error.requestId]) {
57776
57958
  delete requestMap[error.requestId];
57777
57959
  }
@@ -57846,17 +58028,12 @@ function NetworkCapture() {
57846
58028
  buffer.clear();
57847
58029
  return;
57848
58030
  }
57849
- const jzb = buffer.pack();
57850
- const queryParams = {
57851
- v: globalPendo.VERSION,
57852
- ct: pluginAPI.util.getNow()
57853
- };
57854
- const url = pluginAPI.transmit.buildBaseDataUrl(DEV_LOG_TYPE, globalPendo.apiKey, queryParams);
58031
+ const payloads = buffer.pack();
57855
58032
  if (unload || hidden) {
57856
- sendQueue.drain([{ url, jzb }], unload);
58033
+ sendQueue.drain(payloads, unload);
57857
58034
  }
57858
58035
  else {
57859
- sendQueue.push({ url, jzb });
58036
+ sendQueue.push(...payloads);
57860
58037
  }
57861
58038
  }
57862
58039
  }