@pendo/agent 2.299.0 → 2.300.0

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.
@@ -3905,8 +3905,8 @@ let SERVER = '';
3905
3905
  let ASSET_HOST = '';
3906
3906
  let ASSET_PATH = '';
3907
3907
  let DESIGNER_SERVER = '';
3908
- let VERSION = '2.299.0_';
3909
- let PACKAGE_VERSION = '2.299.0';
3908
+ let VERSION = '2.300.0_';
3909
+ let PACKAGE_VERSION = '2.300.0';
3910
3910
  let LOADER = 'xhr';
3911
3911
  /* eslint-enable agent-eslint-rules/no-gulp-env-references */
3912
3912
  /**
@@ -11560,7 +11560,7 @@ var loadResource = function (options, callback, sendErrorToCallback = false) {
11560
11560
  script.src = getPolicy(pendo$1).createScriptURL(options.url);
11561
11561
  addIntegrityAttribute(script, options.url);
11562
11562
  document.body.appendChild(script);
11563
- return {};
11563
+ return script;
11564
11564
  }
11565
11565
  else { // Assume JS file.
11566
11566
  script = document.createElement('script');
@@ -11574,7 +11574,7 @@ var loadResource = function (options, callback, sendErrorToCallback = false) {
11574
11574
  if (err) {
11575
11575
  if (sendErrorToCallback)
11576
11576
  originalCallback(err);
11577
- return;
11577
+ return {};
11578
11578
  }
11579
11579
  originalCallback.apply(this, _.toArray(arguments).slice(1));
11580
11580
  });
@@ -11628,7 +11628,7 @@ var loadWatcher = function (target, url, callback) {
11628
11628
  setTimeout$1(function () {
11629
11629
  if (!isLoaded) {
11630
11630
  // Log a warning if we fail to load the resource within 10 seconds
11631
- writeMessage('Failed to load ' + url + ' within 10 seconds');
11631
+ log.critical('Failed to load ' + url + ' within 10 seconds');
11632
11632
  }
11633
11633
  }, 10000);
11634
11634
  }
@@ -12278,6 +12278,8 @@ class PerformanceMonitor {
12278
12278
  this.measures = new Set();
12279
12279
  }
12280
12280
  initialize() {
12281
+ if (!ConfigReader.get('performanceMetricsEnabled'))
12282
+ return _.noop;
12281
12283
  this._measuringPerformance = true;
12282
12284
  this._markPerformance(INITIALIZE);
12283
12285
  this.interval = setInterval(() => {
@@ -12306,25 +12308,20 @@ class PerformanceMonitor {
12306
12308
  this._markPerformance(name, { detail });
12307
12309
  }
12308
12310
  send() {
12309
- const metrics = _.reduce(METRICS, (acc, metric) => {
12311
+ const payload = _.reduce(METRICS, (acc, metric) => {
12310
12312
  const { name, type, instrument } = metric;
12311
12313
  if (!instrument)
12312
12314
  return acc;
12313
12315
  const entries = performance.getEntriesByName(name);
12314
12316
  const value = instrument(entries);
12315
- if (type === 'counter' && value > 0) {
12316
- acc.push({
12317
- name,
12318
- type,
12319
- value,
12320
- timestamp: Date.now()
12321
- });
12322
- }
12317
+ acc.push({
12318
+ name,
12319
+ type,
12320
+ value,
12321
+ timestamp: Date.now()
12322
+ });
12323
12323
  return acc;
12324
12324
  }, []);
12325
- const payload = _.filter(metrics, (metric) => {
12326
- return metric.value > 0;
12327
- });
12328
12325
  this._clearMarksAndMeasures();
12329
12326
  if (!ConfigReader.get('sendPerformanceMetrics'))
12330
12327
  return;
@@ -12333,8 +12330,7 @@ class PerformanceMonitor {
12333
12330
  }
12334
12331
  }
12335
12332
  _checkPerformanceApi() {
12336
- return ConfigReader.get('performanceMetricsEnabled') &&
12337
- detectNativeBrowserAPI('performance.mark') &&
12333
+ return detectNativeBrowserAPI('performance.mark') &&
12338
12334
  detectNativeBrowserAPI('performance.measure') &&
12339
12335
  detectNativeBrowserAPI('performance.getEntries') &&
12340
12336
  detectNativeBrowserAPI('performance.getEntriesByName') &&
@@ -20988,22 +20984,13 @@ function continueOrCompleteUpdate() {
20988
20984
  * Otherwise, it is the same as calling startGuides.
20989
20985
  */
20990
20986
  var manuallyStartGuides = function () {
20991
- var originalOptions = ConfigReader.getLocalConfig();
20992
- if (ConfigReader.get('delayGuides')) {
20993
- delete originalOptions.delayGuides;
20994
- ConfigReader.setLocalConfig(originalOptions);
20995
- }
20996
- if (ConfigReader.get('guides.delay')) {
20997
- delete originalOptions.guides.delay;
20998
- ConfigReader.setLocalConfig(originalOptions);
20999
- }
20987
+ setGuidesDelayed(false);
21000
20988
  startGuides();
21001
20989
  };
21002
20990
  var manuallyStopGuides = function () {
21003
20991
  if (!areGuidesDisabled()) {
21004
20992
  setGuidesDelayed(true);
21005
20993
  }
21006
- stopGuides();
21007
20994
  resetPendoUI();
21008
20995
  };
21009
20996
  // a phase that only has one unit of work per update
@@ -24268,30 +24255,40 @@ class GuideCache {
24268
24255
  if (this.db)
24269
24256
  return q.resolve(this.db);
24270
24257
  const deferred = q.defer();
24271
- const request = indexedDB.open(`pendo-${apiKey}`, 1);
24272
- request.onerror = () => {
24273
- log.warn('Error opening guide database');
24274
- this.cacheGuidesPersistent = false;
24275
- deferred.resolve();
24276
- };
24277
- request.onsuccess = (event) => {
24278
- const db = event.target.result;
24279
- this.db = db;
24280
- db.onclose = () => {
24281
- this.db = null;
24258
+ try {
24259
+ const request = indexedDB.open(`pendo-${apiKey}`, 1);
24260
+ request.onerror = () => {
24261
+ this.dbError(new Error('open.request.onerror'));
24262
+ deferred.resolve();
24282
24263
  };
24283
- deferred.resolve(db);
24284
- };
24285
- request.onupgradeneeded = (event) => {
24286
- const db = event.target.result;
24287
- const objectStore = db.createObjectStore('guides', { keyPath: 'guide.id' });
24288
- objectStore.transaction.oncomplete = () => {
24264
+ request.onsuccess = (event) => {
24265
+ const db = event.target.result;
24289
24266
  this.db = db;
24267
+ db.onclose = () => {
24268
+ this.db = null;
24269
+ };
24290
24270
  deferred.resolve(db);
24291
24271
  };
24292
- };
24272
+ request.onupgradeneeded = (event) => {
24273
+ const db = event.target.result;
24274
+ const objectStore = db.createObjectStore('guides', { keyPath: 'guide.id' });
24275
+ objectStore.transaction.oncomplete = () => {
24276
+ this.db = db;
24277
+ deferred.resolve(db);
24278
+ };
24279
+ };
24280
+ }
24281
+ catch (error) {
24282
+ this.dbError(error);
24283
+ deferred.resolve();
24284
+ }
24293
24285
  return deferred.promise;
24294
24286
  }
24287
+ dbError(error) {
24288
+ log.critical('indexedDB cache error', { error });
24289
+ this.cacheGuidesPersistent = false;
24290
+ this.db = null;
24291
+ }
24295
24292
  load(now = getNow()) {
24296
24293
  if (this.cache)
24297
24294
  return q.resolve(this.cache);
@@ -24299,26 +24296,30 @@ class GuideCache {
24299
24296
  if (!this.db)
24300
24297
  return q.resolve(this.cache);
24301
24298
  const deferred = q.defer();
24302
- const objectStore = this.db.transaction(['guides'], 'readwrite').objectStore('guides');
24303
- const request = objectStore.getAll();
24304
- request.onerror = () => {
24305
- log.warn('Error loading guide cache');
24306
- this.cacheGuidesPersistent = false;
24307
- this.db = null;
24308
- deferred.resolve(this.cache);
24309
- };
24310
- request.onsuccess = (event) => {
24311
- const cachedGuides = event.target.result;
24312
- _.each(cachedGuides, (cachedGuide) => {
24313
- if (cachedGuide.expires > now) {
24314
- this.cache[cachedGuide.guide.id] = cachedGuide;
24315
- }
24316
- else {
24317
- objectStore.delete(cachedGuide.guide.id);
24318
- }
24319
- });
24299
+ try {
24300
+ const objectStore = this.db.transaction(['guides'], 'readwrite').objectStore('guides');
24301
+ const request = objectStore.getAll();
24302
+ request.onerror = () => {
24303
+ this.dbError(new Error('load.request.onerror'));
24304
+ deferred.resolve(this.cache);
24305
+ };
24306
+ request.onsuccess = (event) => {
24307
+ const cachedGuides = event.target.result;
24308
+ _.each(cachedGuides, (cachedGuide) => {
24309
+ if (cachedGuide.expires > now) {
24310
+ this.cache[cachedGuide.guide.id] = cachedGuide;
24311
+ }
24312
+ else {
24313
+ objectStore.delete(cachedGuide.guide.id);
24314
+ }
24315
+ });
24316
+ deferred.resolve(this.cache);
24317
+ };
24318
+ }
24319
+ catch (error) {
24320
+ this.dbError(error);
24320
24321
  deferred.resolve(this.cache);
24321
- };
24322
+ }
24322
24323
  return deferred.promise;
24323
24324
  }
24324
24325
  add(guide, visitorId, now = getNow()) {
@@ -24337,16 +24338,22 @@ class GuideCache {
24337
24338
  save(cachedGuide) {
24338
24339
  if (!this.db)
24339
24340
  return;
24340
- const objectStore = this.db.transaction(['guides'], 'readwrite').objectStore('guides');
24341
24341
  const deferred = q.defer();
24342
- const update = objectStore.put(cachedGuide);
24343
- update.onerror = () => {
24344
- log.warn(`Error saving guide to cache ${cachedGuide.guide.id}`);
24345
- deferred.resolve();
24346
- };
24347
- update.onsuccess = () => {
24342
+ try {
24343
+ const objectStore = this.db.transaction(['guides'], 'readwrite').objectStore('guides');
24344
+ const update = objectStore.put(cachedGuide);
24345
+ update.onerror = () => {
24346
+ this.dbError(new Error('save.request.onerror'));
24347
+ deferred.resolve();
24348
+ };
24349
+ update.onsuccess = () => {
24350
+ deferred.resolve();
24351
+ };
24352
+ }
24353
+ catch (error) {
24354
+ this.dbError(error);
24348
24355
  deferred.resolve();
24349
- };
24356
+ }
24350
24357
  return deferred.promise;
24351
24358
  }
24352
24359
  update(lastGuideStepSeen) {
@@ -25915,13 +25922,12 @@ var loadGuides = function (apiKey, visitorId, page, callback) {
25915
25922
  }
25916
25923
  if (displayableGuides.length) {
25917
25924
  q.all([
25918
- loadGuideCss(),
25919
25925
  globalJsPromise,
25920
25926
  initializeResourceCenter(activeGuides),
25921
25927
  BuildingBlockWatermark.initializeWatermark(activeGuides),
25922
25928
  waitForGlobalCssToLoad(5000)
25923
25929
  ]
25924
- .concat(getRegisteredLoadGuideJobs(activeGuides))).then(function () {
25930
+ .concat(getRegisteredLoadGuideJobs(activeGuides), loadGuideCss())).then(function () {
25925
25931
  if (loadGuides.reqId === reqId) {
25926
25932
  if (store.getters['frames/isLeader']()) {
25927
25933
  restoreGuideShownState(getActiveGuides());
@@ -25935,7 +25941,8 @@ var loadGuides = function (apiKey, visitorId, page, callback) {
25935
25941
  }
25936
25942
  deferred.resolve();
25937
25943
  }, function (err) {
25938
- log.error('Post loadGuide request failed: ', err);
25944
+ log.critical(`Post loadGuide request failed: ${err}`);
25945
+ resetPendoUI();
25939
25946
  Events.guidesFailed.trigger();
25940
25947
  deferred.reject();
25941
25948
  });
@@ -25990,6 +25997,9 @@ function loadExternalCss(id, cssUrl) {
25990
25997
  var style = pendo$1.loadResource(cssUrl, function () {
25991
25998
  deferred.resolve();
25992
25999
  });
26000
+ if (_.isEmpty(style)) {
26001
+ return q.reject(`Failed to load CSS resource: ${cssUrl}. Check that the URL is correct and from an allowed origin.`);
26002
+ }
25993
26003
  style.id = id;
25994
26004
  return deferred.promise;
25995
26005
  }
@@ -26068,7 +26078,7 @@ function loadGuideCss() {
26068
26078
  else {
26069
26079
  dom('#' + CUSTOM_CSS_ID).remove();
26070
26080
  }
26071
- return q.all(promises);
26081
+ return promises;
26072
26082
  }
26073
26083
  var processGuideEventCache = function (options) {
26074
26084
  if (!guideEventQueue)
@@ -26220,14 +26230,6 @@ var initGuides = function (observer) {
26220
26230
  teardownFns.push(attachEventInternal(window, 'securitypolicyviolation', securityPolicyViolationFn));
26221
26231
  teardownFns.push(createVideoFullScreenListeners());
26222
26232
  if (observer.observing) {
26223
- var updateGuide = function () {
26224
- store.dispatch('guideUpdate/documentChanged');
26225
- };
26226
- const debouncedUpdate = _.debounce(updateGuide, 50);
26227
- teardownFns.push(() => { debouncedUpdate.cancel(); });
26228
- teardownFns.push(attachEvent(window, 'animationend', debouncedUpdate));
26229
- teardownFns.push(attachEvent(window, 'transitionend', debouncedUpdate));
26230
- teardownFns.push(attachEvent(window, 'mouseover', debouncedUpdate));
26231
26233
  store.commit('guideUpdate/setObserver', observer);
26232
26234
  store.commit('guideUpdate/setUseObserver');
26233
26235
  teardownFns.push(() => store.dispatch('guideUpdate/stopObserver'));
@@ -26318,6 +26320,10 @@ var setGuidesDisabled = function (areDisabled) {
26318
26320
  };
26319
26321
  var setGuidesDelayed = function (areDelayed) {
26320
26322
  var originalOptions = ConfigReader.getLocalConfig();
26323
+ delete originalOptions.delayGuides;
26324
+ if (originalOptions.guides) {
26325
+ delete originalOptions.guides.delay;
26326
+ }
26321
26327
  originalOptions.delayGuides = areDelayed;
26322
26328
  ConfigReader.setLocalConfig(originalOptions);
26323
26329
  };
@@ -33471,6 +33477,7 @@ var GuideUpdateModule = (function () {
33471
33477
  function observerCallback() {
33472
33478
  store.dispatch('guideUpdate/documentChanged');
33473
33479
  }
33480
+ const debouncedCallback = _.debounce(observerCallback, 50);
33474
33481
  function handleScheduledUpdate() {
33475
33482
  store.dispatch('guideUpdate/handleScheduledUpdate');
33476
33483
  }
@@ -33511,6 +33518,9 @@ var GuideUpdateModule = (function () {
33511
33518
  if (!context.state.observing) {
33512
33519
  const observer = context.getters.observer();
33513
33520
  observer.addEventListener('mutation', observerCallback);
33521
+ attachEvent(window, 'animationend', debouncedCallback);
33522
+ attachEvent(window, 'transitionend', debouncedCallback);
33523
+ attachEvent(window, 'mouseover', debouncedCallback);
33514
33524
  context.commit('setObserving', true);
33515
33525
  }
33516
33526
  }
@@ -33519,6 +33529,10 @@ var GuideUpdateModule = (function () {
33519
33529
  const observer = context.getters.observer();
33520
33530
  if (observer) {
33521
33531
  observer.removeEventListener('mutation', observerCallback);
33532
+ debouncedCallback.cancel();
33533
+ detachEvent(window, 'animationend', debouncedCallback);
33534
+ detachEvent(window, 'transitionend', debouncedCallback);
33535
+ detachEvent(window, 'mouseover', debouncedCallback);
33522
33536
  }
33523
33537
  context.commit('setObserving', false);
33524
33538
  context.dispatch('stopScheduledUpdate');
@@ -39811,7 +39825,7 @@ class PromptPlugin {
39811
39825
  promptType: method,
39812
39826
  url,
39813
39827
  privacyFilterApplied: filteredPrompt !== originalBody
39814
- });
39828
+ }, undefined, 'agentic');
39815
39829
  });
39816
39830
  }
39817
39831
  handleError({ error, context }) {
@@ -39853,7 +39867,7 @@ class PromptPlugin {
39853
39867
  promptType: 'request',
39854
39868
  agentType: 'prompt'
39855
39869
  }, promptEvent);
39856
- this.api.analytics.collectEvent('prompt', event);
39870
+ this.api.analytics.collectEvent('prompt', event, undefined, 'agentic');
39857
39871
  }
39858
39872
  teardown() {
39859
39873
  this._.each(this.prompts, (prompt) => prompt.teardown());
@@ -45064,6 +45078,9 @@ class MutationBuffer {
45064
45078
  this.movedMap = {};
45065
45079
  this.mutationCb(payload);
45066
45080
  });
45081
+ __publicField(this, "bufferBelongsToIframe", (iframeEl) => {
45082
+ return this.doc === iframeEl.contentDocument;
45083
+ });
45067
45084
  __publicField(this, "genTextAreaValueMutation", (textarea) => {
45068
45085
  let item = this.attributeMap.get(textarea);
45069
45086
  if (!item) {
@@ -45631,6 +45648,15 @@ function initViewportResizeObserver({ viewportResizeCb }, { win }) {
45631
45648
  );
45632
45649
  return on("resize", updateDimension, win);
45633
45650
  }
45651
+ function findAndRemoveIframeBuffer(iframeEl) {
45652
+ for (let i2 = mutationBuffers.length - 1; i2 >= 0; i2--) {
45653
+ const buf = mutationBuffers[i2];
45654
+ if (buf.bufferBelongsToIframe(iframeEl)) {
45655
+ buf.reset();
45656
+ mutationBuffers.splice(i2, 1);
45657
+ }
45658
+ }
45659
+ }
45634
45660
  const INPUT_TAGS = ["INPUT", "TEXTAREA", "SELECT"];
45635
45661
  const lastInputValueMap = /* @__PURE__ */ new WeakMap();
45636
45662
  function initInputObserver({
@@ -46477,6 +46503,7 @@ class IframeManager {
46477
46503
  __publicField(this, "wrappedEmit");
46478
46504
  __publicField(this, "takeFullSnapshot");
46479
46505
  __publicField(this, "loadListener");
46506
+ __publicField(this, "pageHideListener");
46480
46507
  __publicField(this, "stylesheetManager");
46481
46508
  __publicField(this, "recordCrossOriginIframes");
46482
46509
  this.mutationCb = options.mutationCb;
@@ -46514,6 +46541,9 @@ class IframeManager {
46514
46541
  addLoadListener(cb) {
46515
46542
  this.loadListener = cb;
46516
46543
  }
46544
+ addPageHideListener(cb) {
46545
+ this.pageHideListener = cb;
46546
+ }
46517
46547
  attachIframe(iframeEl, childSn) {
46518
46548
  var _a2, _b, _c;
46519
46549
  this.mutationCb({
@@ -46535,6 +46565,9 @@ class IframeManager {
46535
46565
  this.handleMessage.bind(this)
46536
46566
  );
46537
46567
  (_b = iframeEl.contentWindow) == null ? void 0 : _b.addEventListener("pagehide", () => {
46568
+ var _a3;
46569
+ (_a3 = this.pageHideListener) == null ? void 0 : _a3.call(this, iframeEl);
46570
+ this.mirror.removeNodeFromMap(iframeEl.contentDocument);
46538
46571
  this.crossOriginIframeMap.delete(iframeEl.contentWindow);
46539
46572
  });
46540
46573
  }
@@ -47748,6 +47781,7 @@ function record(options = {}) {
47748
47781
  iframeManager.setTakeFullSnapshot(takeFullSnapshot$1);
47749
47782
  try {
47750
47783
  const handlers = [];
47784
+ const iframeHandlersMap = /* @__PURE__ */ new Map();
47751
47785
  const observe = (doc) => {
47752
47786
  var _a2;
47753
47787
  return callbackWrapper(initObservers)(
@@ -47873,11 +47907,19 @@ function record(options = {}) {
47873
47907
  };
47874
47908
  iframeManager.addLoadListener((iframeEl) => {
47875
47909
  try {
47876
- handlers.push(observe(iframeEl.contentDocument));
47910
+ iframeHandlersMap.set(iframeEl, observe(iframeEl.contentDocument));
47877
47911
  } catch (error) {
47878
47912
  console.warn(error);
47879
47913
  }
47880
47914
  });
47915
+ iframeManager.addPageHideListener((iframeEl) => {
47916
+ const iframeHandler = iframeHandlersMap.get(iframeEl);
47917
+ if (iframeHandler) {
47918
+ iframeHandler();
47919
+ iframeHandlersMap.delete(iframeEl);
47920
+ }
47921
+ findAndRemoveIframeBuffer(iframeEl);
47922
+ });
47881
47923
  const init = () => {
47882
47924
  takeFullSnapshot$1();
47883
47925
  handlers.push(observe(document));
@@ -47911,6 +47953,7 @@ function record(options = {}) {
47911
47953
  }
47912
47954
  return () => {
47913
47955
  handlers.forEach((h) => h());
47956
+ iframeHandlersMap.forEach((h) => h());
47914
47957
  processedNodeManager.destroy();
47915
47958
  recording = false;
47916
47959
  unregisterErrorHandler();