@openreplay/tracker 17.2.3 → 17.2.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.
@@ -15,13 +15,15 @@ declare class Batcher {
15
15
  private readonly backendUrl;
16
16
  private readonly getToken;
17
17
  private readonly init;
18
+ private readonly standalone;
18
19
  private readonly autosendInterval;
19
20
  private readonly retryTimeout;
20
21
  private readonly retryLimit;
21
22
  private readonly apiEdp;
22
23
  private batch;
23
24
  private intervalId;
24
- constructor(backendUrl: string, getToken: () => string | null, init: () => Promise<void>);
25
+ private stopped;
26
+ constructor(backendUrl: string, getToken: () => string | null, init: () => Promise<void>, standalone: boolean);
25
27
  getBatches(): {
26
28
  data: {
27
29
  user_actions: PeopleEvent[];
@@ -38,8 +40,11 @@ declare class Batcher {
38
40
  dedupePeopleEvents(): PeopleEvent[];
39
41
  private squashPeopleEvents;
40
42
  private sendBatch;
43
+ private paused;
44
+ private onVisibilityChange;
41
45
  startAutosend(): void;
42
46
  flush(): void;
43
47
  stop(): void;
48
+ restart(): void;
44
49
  }
45
50
  export default Batcher;
@@ -51,6 +51,11 @@ export default class Analytics {
51
51
  _getToken: () => string | null;
52
52
  _getTimestamp: () => number;
53
53
  init: () => Promise<void>;
54
+ /**
55
+ * Used by tracker when running in blundled mode
56
+ */
57
+ onStart: () => void;
58
+ onStop: () => void;
54
59
  reset: () => void;
55
60
  /**
56
61
  * COMPATIBILITY LAYER
package/dist/lib/entry.js CHANGED
@@ -3848,7 +3848,7 @@ class App {
3848
3848
  this.stopCallbacks = [];
3849
3849
  this.commitCallbacks = [];
3850
3850
  this.activityState = ActivityState.NotActive;
3851
- this.version = '17.2.3'; // TODO: version compatability check inside each plugin.
3851
+ this.version = '17.2.4'; // TODO: version compatability check inside each plugin.
3852
3852
  this.socketMode = false;
3853
3853
  this.compressionThreshold = 24 * 1000;
3854
3854
  this.bc = null;
@@ -6172,7 +6172,7 @@ function getUniqueSiblingClass(el) {
6172
6172
  return null;
6173
6173
  }
6174
6174
 
6175
- let e=-1;const t=t=>{addEventListener("pageshow",(n=>{n.persisted&&(e=n.timeStamp,t(n));}),true);},n=(e,t,n,i)=>{let s,o;return r=>{t.value>=0&&(r||i)&&(o=t.value-(s??0),(o||void 0===s)&&(s=t.value,t.delta=o,t.rating=((e,t)=>e>t[1]?"poor":e>t[0]?"needs-improvement":"good")(t.value,n),e(t)));}},i=e=>{requestAnimationFrame((()=>requestAnimationFrame((()=>e()))));},s=()=>{const e=performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},o=()=>{const e=s();return e?.activationStart??0},r=(t,n=-1)=>{const i=s();let r="navigate";e>=0?r="back-forward-cache":i&&(document.prerendering||o()>0?r="prerender":document.wasDiscarded?r="restore":i.type&&(r=i.type.replace(/_/g,"-")));return {name:t,value:n,rating:"good",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:r}},c=new WeakMap;function a(e,t){return c.get(e)||c.set(e,new t),c.get(e)}class d{t;i=0;o=[];h(e){if(e.hadRecentInput)return;const t=this.o[0],n=this.o.at(-1);this.i&&t&&n&&e.startTime-n.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e);}}const h=(e,t,n={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){const i=new PerformanceObserver((e=>{Promise.resolve().then((()=>{t(e.getEntries());}));}));return i.observe({type:e,buffered:!0,...n}),i}}catch{}},f=e=>{let t=false;return ()=>{t||(e(),t=true);}};let u=-1;const l=new Set,m=()=>"hidden"!==document.visibilityState||document.prerendering?1/0:0,p=e=>{if("hidden"===document.visibilityState){if("visibilitychange"===e.type)for(const e of l)e();isFinite(u)||(u="visibilitychange"===e.type?e.timeStamp:0,removeEventListener("prerenderingchange",p,true));}},v=()=>{if(u<0){const e=o(),n=document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").filter((t=>"hidden"===t.name&&t.startTime>e))[0]?.startTime;u=n??m(),addEventListener("visibilitychange",p,true),addEventListener("prerenderingchange",p,true),t((()=>{setTimeout((()=>{u=m();}));}));}return {get firstHiddenTime(){return u},onHidden(e){l.add(e);}}},g=e=>{document.prerendering?addEventListener("prerenderingchange",(()=>e()),true):e();},y=[1800,3e3],E=(e,s={})=>{g((()=>{const c=v();let a,d=r("FCP");const f=h("paint",(e=>{for(const t of e)"first-contentful-paint"===t.name&&(f.disconnect(),t.startTime<c.firstHiddenTime&&(d.value=Math.max(t.startTime-o(),0),d.entries.push(t),a(true)));}));f&&(a=n(e,d,y,s.reportAllChanges),t((t=>{d=r("FCP"),a=n(e,d,y,s.reportAllChanges),i((()=>{d.value=performance.now()-t.timeStamp,a(true);}));})));}));},b=[.1,.25],L=(e,s={})=>{const o=v();E(f((()=>{let c,f=r("CLS",0);const u=a(s,d),l=e=>{for(const t of e)u.h(t);u.i>f.value&&(f.value=u.i,f.entries=u.o,c());},m=h("layout-shift",l);m&&(c=n(e,f,b,s.reportAllChanges),o.onHidden((()=>{l(m.takeRecords()),c(true);})),t((()=>{u.i=0,f=r("CLS",0),c=n(e,f,b,s.reportAllChanges),i((()=>c()));})),setTimeout(c));})));};let P=0,T=1/0,_=0;const M=e=>{for(const t of e)t.interactionId&&(T=Math.min(T,t.interactionId),_=Math.max(_,t.interactionId),P=_?(_-T)/7+1:0);};let w;const C=()=>w?P:performance.interactionCount??0,I=()=>{"interactionCount"in performance||w||(w=h("event",M,{type:"event",buffered:true,durationThreshold:0}));};let F=0;class k{u=[];l=new Map;m;p;v(){F=C(),this.u.length=0,this.l.clear();}L(){const e=Math.min(this.u.length-1,Math.floor((C()-F)/50));return this.u[e]}h(e){if(this.m?.(e),!e.interactionId&&"first-input"!==e.entryType)return;const t=this.u.at(-1);let n=this.l.get(e.interactionId);if(n||this.u.length<10||e.duration>t.P){if(n?e.duration>n.P?(n.entries=[e],n.P=e.duration):e.duration===n.P&&e.startTime===n.entries[0].startTime&&n.entries.push(e):(n={id:e.interactionId,entries:[e],P:e.duration},this.l.set(n.id,n),this.u.push(n)),this.u.sort(((e,t)=>t.P-e.P)),this.u.length>10){const e=this.u.splice(10);for(const t of e)this.l.delete(t.id);}this.p?.(n);}}}const A=e=>{const t=globalThis.requestIdleCallback||setTimeout;"hidden"===document.visibilityState?e():(e=f(e),addEventListener("visibilitychange",e,{once:true,capture:true}),t((()=>{e(),removeEventListener("visibilitychange",e,{capture:true});})));},B=[200,500],S=(e,i={})=>{if(!globalThis.PerformanceEventTiming||!("interactionId"in PerformanceEventTiming.prototype))return;const s=v();g((()=>{I();let o,c=r("INP");const d=a(i,k),f=e=>{A((()=>{for(const t of e)d.h(t);const t=d.L();t&&t.P!==c.value&&(c.value=t.P,c.entries=t.entries,o());}));},u=h("event",f,{durationThreshold:i.durationThreshold??40});o=n(e,c,B,i.reportAllChanges),u&&(u.observe({type:"first-input",buffered:true}),s.onHidden((()=>{f(u.takeRecords()),o(true);})),t((()=>{d.v(),c=r("INP"),o=n(e,c,B,i.reportAllChanges);})));}));};class N{m;h(e){this.m?.(e);}}const q=[2500,4e3],x=(e,s={})=>{g((()=>{const c=v();let d,u=r("LCP");const l=a(s,N),m=e=>{s.reportAllChanges||(e=e.slice(-1));for(const t of e)l.h(t),t.startTime<c.firstHiddenTime&&(u.value=Math.max(t.startTime-o(),0),u.entries=[t],d());},p=h("largest-contentful-paint",m);if(p){d=n(e,u,q,s.reportAllChanges);const o=f((()=>{m(p.takeRecords()),p.disconnect(),d(true);})),c=e=>{e.isTrusted&&(A(o),removeEventListener(e.type,c,{capture:true}));};for(const e of ["keydown","click","visibilitychange"])addEventListener(e,c,{capture:true});t((t=>{u=r("LCP"),d=n(e,u,q,s.reportAllChanges),i((()=>{u.value=performance.now()-t.timeStamp,d(true);}));}));}}));},H=[800,1800],O=e=>{document.prerendering?g((()=>O(e))):"complete"!==document.readyState?addEventListener("load",(()=>O(e)),true):setTimeout(e);},$=(e,i={})=>{let c=r("TTFB"),a=n(e,c,H,i.reportAllChanges);O((()=>{const d=s();d&&(c.value=Math.max(d.responseStart-o(),0),c.entries=[d],a(true),t((()=>{c=r("TTFB",0),a=n(e,c,H,i.reportAllChanges),a(true);})));}));};
6175
+ var e,o=-1,a=function(e){addEventListener("pageshow",(function(n){n.persisted&&(o=n.timeStamp,e(n));}),true);},c=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},u=function(){var e=c();return e&&e.activationStart||0},f=function(e,n){var t=c(),r="navigate";o>=0?r="back-forward-cache":t&&(document.prerendering||u()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-")));return {name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},s=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries());}));}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},d=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n));}},l=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}));},p=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e();}));},v=function(e){var n=false;return function(){n||(e(),n=true);}},m=-1,h=function(){return "hidden"!==document.visibilityState||document.prerendering?1/0:0},g=function(e){"hidden"===document.visibilityState&&m>-1&&(m="visibilitychange"===e.type?e.timeStamp:0,T());},y=function(){addEventListener("visibilitychange",g,true),addEventListener("prerenderingchange",g,true);},T=function(){removeEventListener("visibilitychange",g,true),removeEventListener("prerenderingchange",g,true);},E=function(){return m<0&&(m=h(),y(),a((function(){setTimeout((function(){m=h(),y();}),0);}))),{get firstHiddenTime(){return m}}},C=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),true):e();},b=[1800,3e3],S=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("FCP"),o=s("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries.push(e),t(true)));}));}));o&&(t=d(e,i,b,n.reportAllChanges),a((function(r){i=f("FCP"),t=d(e,i,b,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,t(true);}));})));}));},L=[.1,.25],w=function(e,n){n=n||{},S(v((function(){var t,r=f("CLS",0),i=0,o=[],c=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e]);}})),i>r.value&&(r.value=i,r.entries=o,t());},u=s("layout-shift",c);u&&(t=d(e,r,L,n.reportAllChanges),p((function(){c(u.takeRecords()),t(true);})),a((function(){i=0,r=f("CLS",0),t=d(e,r,L,n.reportAllChanges),l((function(){return t()}));})),setTimeout(t,0));})));},A=0,I=1/0,P=0,M=function(e){e.forEach((function(e){e.interactionId&&(I=Math.min(I,e.interactionId),P=Math.max(P,e.interactionId),A=P?(P-I)/7+1:0);}));},k=function(){return e?A:performance.interactionCount||0},F=function(){"interactionCount"in performance||e||(e=s("event",M,{type:"event",buffered:true,durationThreshold:0}));},D=[],x=new Map,R=0,B=function(){var e=Math.min(D.length-1,Math.floor((k()-R)/50));return D[e]},H=[],q=function(e){if(H.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=D[D.length-1],t=x.get(e.interactionId);if(t||D.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else {var r={id:e.interactionId,latency:e.duration,entries:[e]};x.set(r.id,r),D.push(r);}D.sort((function(e,n){return n.latency-e.latency})),D.length>10&&D.splice(10).forEach((function(e){return x.delete(e.id)}));}}},O=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=v(e),"hidden"===document.visibilityState?e():(t=n(e),p(e)),t},N=[200,500],j=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},C((function(){var t;F();var r,i=f("INP"),o=function(e){O((function(){e.forEach(q);var n=B();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r());}));},c=s("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=d(e,i,N,n.reportAllChanges),c&&(c.observe({type:"first-input",buffered:true}),p((function(){o(c.takeRecords()),r(true);})),a((function(){R=k(),D.length=0,x.clear(),i=f("INP"),r=d(e,i,N,n.reportAllChanges);})));})));},_=[2500,4e3],z={},G=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries=[e],t());}));},c=s("largest-contentful-paint",o);if(c){t=d(e,i,_,n.reportAllChanges);var m=v((function(){z[i.id]||(o(c.takeRecords()),c.disconnect(),z[i.id]=true,t(true));}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return O(m)}),{once:true,capture:true});})),p(m),a((function(r){i=f("LCP"),t=d(e,i,_,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,z[i.id]=true,t(true);}));}));}}));},J=[800,1800],K=function e(n){document.prerendering?C((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),true):setTimeout(n,0);},Q=function(e,n){n=n||{};var t=f("TTFB"),r=d(e,t,J,n.reportAllChanges);K((function(){var i=c();i&&(t.value=Math.max(i.responseStart-u(),0),t.entries=[i],r(true),a((function(){t=f("TTFB",0),(r=d(e,t,J,n.reportAllChanges))(true);})));}));};
6176
6176
 
6177
6177
  function getPaintBlocks(resources) {
6178
6178
  const paintBlocks = [];
@@ -6305,10 +6305,10 @@ function Timing (app, opts) {
6305
6305
  // onINP(): Chromium
6306
6306
  // onLCP(): Chromium, Firefox
6307
6307
  // onTTFB(): Chromium, Firefox, Safari
6308
- L(onVitalsSignal);
6309
- S(onVitalsSignal);
6310
- x(onVitalsSignal);
6311
- $(onVitalsSignal);
6308
+ w(onVitalsSignal);
6309
+ j(onVitalsSignal);
6310
+ G(onVitalsSignal);
6311
+ Q(onVitalsSignal);
6312
6312
  });
6313
6313
  app.attachStopCallback(function () {
6314
6314
  observer.disconnect();
@@ -7109,9 +7109,7 @@ class NetworkMessage {
7109
7109
  });
7110
7110
  if (!messageInfo)
7111
7111
  return null;
7112
- const gqlHeader = "application/graphql-response";
7113
- const isGraphql = messageInfo.url.includes("/graphql")
7114
- || Object.values(messageInfo.request.headers).some(v => v.includes(gqlHeader));
7112
+ const isGraphql = messageInfo.url.includes("/graphql");
7115
7113
  if (isGraphql && messageInfo.response.body && typeof messageInfo.response.body === 'string') {
7116
7114
  const isError = messageInfo.response.body.includes("errors");
7117
7115
  messageInfo.status = isError ? 400 : 200;
@@ -7417,7 +7415,6 @@ class FetchProxyHandler {
7417
7415
  this.tokenUrlMatcher = tokenUrlMatcher;
7418
7416
  }
7419
7417
  apply(target, _, argsList) {
7420
- var _a;
7421
7418
  const input = argsList[0];
7422
7419
  const init = argsList[1];
7423
7420
  if (!input ||
@@ -7433,31 +7430,6 @@ class FetchProxyHandler {
7433
7430
  }
7434
7431
  const item = new NetworkMessage(this.ignoredHeaders, this.setSessionTokenHeader, this.sanitize);
7435
7432
  this.beforeFetch(item, input, init);
7436
- const signal = (argsList[0] instanceof Request ? argsList[0].signal : undefined) ||
7437
- ((_a = argsList[1]) === null || _a === void 0 ? void 0 : _a.signal);
7438
- // guard to avoid double-send
7439
- let abortedNotified = false;
7440
- const notifyAbort = () => {
7441
- if (abortedNotified)
7442
- return;
7443
- abortedNotified = true;
7444
- item.endTime = performance.now();
7445
- item.duration = item.endTime - (item.startTime || item.endTime);
7446
- item.status = 0;
7447
- item.statusText = "Aborted";
7448
- item.readyState = 0;
7449
- const msg = item.getMessage();
7450
- if (msg)
7451
- this.sendMessage(msg);
7452
- };
7453
- if (signal) {
7454
- if (signal.aborted) {
7455
- notifyAbort();
7456
- }
7457
- else {
7458
- signal.addEventListener("abort", notifyAbort, { once: true });
7459
- }
7460
- }
7461
7433
  this.setSessionTokenHeader((name, value) => {
7462
7434
  if (this.tokenUrlMatcher !== undefined) {
7463
7435
  if (!this.tokenUrlMatcher(item.url)) {
@@ -7486,22 +7458,11 @@ class FetchProxyHandler {
7486
7458
  }
7487
7459
  });
7488
7460
  return target.apply(window, argsList)
7489
- .then(this.afterFetch(item, () => {
7490
- abortedNotified = true;
7491
- }))
7461
+ .then(this.afterFetch(item))
7492
7462
  .catch((e) => {
7463
+ // mock finally
7493
7464
  item.endTime = performance.now();
7494
7465
  item.duration = item.endTime - (item.startTime || item.endTime);
7495
- if (e && e.name === "AbortError") {
7496
- item.status = 0;
7497
- item.statusText = "Aborted";
7498
- item.readyState = 0;
7499
- if (!abortedNotified) {
7500
- const msg = item.getMessage();
7501
- if (msg)
7502
- this.sendMessage(msg);
7503
- }
7504
- }
7505
7466
  throw e;
7506
7467
  });
7507
7468
  }
@@ -7553,10 +7514,8 @@ class FetchProxyHandler {
7553
7514
  item.requestData = genStringBody(init.body);
7554
7515
  }
7555
7516
  }
7556
- afterFetch(item, onResolved) {
7517
+ afterFetch(item) {
7557
7518
  return (resp) => {
7558
- if (onResolved)
7559
- onResolved === null || onResolved === void 0 ? void 0 : onResolved();
7560
7519
  item.endTime = performance.now();
7561
7520
  item.duration = item.endTime - (item.startTime || item.endTime);
7562
7521
  item.status = resp.status;
@@ -7592,15 +7551,7 @@ class FetchProxyHandler {
7592
7551
  }
7593
7552
  })
7594
7553
  .catch((e) => {
7595
- if (e.name === "AbortError") {
7596
- item.status = 0;
7597
- item.statusText = "Aborted";
7598
- item.readyState = 0;
7599
- const msg = item.getMessage();
7600
- if (msg)
7601
- this.sendMessage(msg);
7602
- }
7603
- else {
7554
+ if (e.name !== "AbortError") {
7604
7555
  throw e;
7605
7556
  }
7606
7557
  });
@@ -8701,7 +8652,7 @@ class ConstantProperties {
8701
8652
  user_id: this.user_id,
8702
8653
  distinct_id: this.deviceId,
8703
8654
  sdk_edition: 'web',
8704
- sdk_version: '17.2.3',
8655
+ sdk_version: '17.2.4',
8705
8656
  timezone: getUTCOffsetString(),
8706
8657
  search_engine: this.searchEngine,
8707
8658
  };
@@ -9034,10 +8985,11 @@ class People {
9034
8985
  * Creates batches of events, then sends them at intervals.
9035
8986
  */
9036
8987
  class Batcher {
9037
- constructor(backendUrl, getToken, init) {
8988
+ constructor(backendUrl, getToken, init, standalone) {
9038
8989
  this.backendUrl = backendUrl;
9039
8990
  this.getToken = getToken;
9040
8991
  this.init = init;
8992
+ this.standalone = standalone;
9041
8993
  this.autosendInterval = 5 * 1000;
9042
8994
  this.retryTimeout = 3 * 1000;
9043
8995
  this.retryLimit = 3;
@@ -9047,10 +8999,20 @@ class Batcher {
9047
8999
  [categories.events]: [],
9048
9000
  };
9049
9001
  this.intervalId = null;
9002
+ this.stopped = false;
9003
+ this.paused = false;
9004
+ this.onVisibilityChange = () => {
9005
+ this.paused = document.hidden;
9006
+ };
9050
9007
  }
9051
9008
  getBatches() {
9052
9009
  this.batch[categories.people] = this.dedupePeopleEvents();
9053
- const finalData = { data: this.batch };
9010
+ const finalData = {
9011
+ data: {
9012
+ [categories.people]: [...this.batch[categories.people]],
9013
+ [categories.events]: [...this.batch[categories.events]],
9014
+ },
9015
+ };
9054
9016
  return finalData;
9055
9017
  }
9056
9018
  addEvent(event) {
@@ -9126,6 +9088,9 @@ class Batcher {
9126
9088
  return Array.from(uniqueEventsByType.values());
9127
9089
  }
9128
9090
  sendBatch(batch) {
9091
+ if (this.stopped) {
9092
+ return;
9093
+ }
9129
9094
  const sentBatch = batch;
9130
9095
  let attempts = 0;
9131
9096
  const send = () => {
@@ -9142,8 +9107,21 @@ class Batcher {
9142
9107
  },
9143
9108
  body: JSON.stringify(sentBatch),
9144
9109
  })
9145
- .then((response) => {
9146
- if ([403, 401].includes(response.status)) {
9110
+ .then(async (response) => {
9111
+ if (response.status === 401) {
9112
+ const body = await response.json().catch(() => null);
9113
+ if (!this.standalone && body?.error === 'token expired') {
9114
+ this.stop();
9115
+ return;
9116
+ }
9117
+ if (attempts < this.retryLimit) {
9118
+ return this.init().then(() => {
9119
+ send();
9120
+ });
9121
+ }
9122
+ return;
9123
+ }
9124
+ if (response.status === 403) {
9147
9125
  if (attempts < this.retryLimit) {
9148
9126
  return this.init().then(() => {
9149
9127
  send();
@@ -9167,8 +9145,12 @@ class Batcher {
9167
9145
  if (this.intervalId) {
9168
9146
  clearInterval(this.intervalId);
9169
9147
  }
9148
+ this.paused = document.hidden;
9149
+ document.addEventListener('visibilitychange', this.onVisibilityChange);
9170
9150
  this.intervalId = setInterval(() => {
9171
- this.flush();
9151
+ if (!this.paused) {
9152
+ this.flush();
9153
+ }
9172
9154
  }, this.autosendInterval);
9173
9155
  }
9174
9156
  flush() {
@@ -9188,6 +9170,12 @@ class Batcher {
9188
9170
  clearInterval(this.intervalId);
9189
9171
  this.intervalId = null;
9190
9172
  }
9173
+ document.removeEventListener('visibilitychange', this.onVisibilityChange);
9174
+ this.stopped = true;
9175
+ }
9176
+ restart() {
9177
+ this.stopped = false;
9178
+ this.startAutosend();
9191
9179
  }
9192
9180
  }
9193
9181
 
@@ -9254,6 +9242,19 @@ class Analytics {
9254
9242
  }
9255
9243
  }
9256
9244
  };
9245
+ /**
9246
+ * Used by tracker when running in blundled mode
9247
+ */
9248
+ this.onStart = () => {
9249
+ if (!this.standalone) {
9250
+ this.batcher.restart();
9251
+ }
9252
+ };
9253
+ this.onStop = () => {
9254
+ if (!this.standalone) {
9255
+ this.batcher.stop();
9256
+ }
9257
+ };
9257
9258
  this.reset = () => {
9258
9259
  this.people.reset(true);
9259
9260
  this.events.reset();
@@ -9292,7 +9293,7 @@ class Analytics {
9292
9293
  this.standalone = !options.notStandalone;
9293
9294
  this.token = this.sessionStorage.getItem(STORAGEKEY);
9294
9295
  this.constantProperties = new ConstantProperties(this.localStorage, this.sessionStorage);
9295
- this.batcher = new Batcher(this.backendUrl, this._getToken, this.init);
9296
+ this.batcher = new Batcher(this.backendUrl, this._getToken, this.init, this.standalone);
9296
9297
  this.events = new Events(this.constantProperties, this._getTimestamp, this.batcher);
9297
9298
  this.people = new People(this.constantProperties, this._getTimestamp, this.setUserId, this.batcher);
9298
9299
  if (options.notStandalone) {
@@ -9353,7 +9354,7 @@ class API {
9353
9354
  this.signalStartIssue = (reason, missingApi) => {
9354
9355
  const doNotTrack = this.checkDoNotTrack();
9355
9356
  console.log("Tracker couldn't start due to:", JSON.stringify({
9356
- trackerVersion: '17.2.3',
9357
+ trackerVersion: '17.2.4',
9357
9358
  projectKey: this.options.projectKey,
9358
9359
  doNotTrack,
9359
9360
  reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
@@ -9505,6 +9506,12 @@ class API {
9505
9506
  : (options.analytics?.ingestPoint ?? options.ingestPoint ?? defaultEdp),
9506
9507
  projectKey: options.projectKey,
9507
9508
  });
9509
+ app.attachStartCallback(() => {
9510
+ this.analytics?.onStart();
9511
+ });
9512
+ app.attachStopCallback(() => {
9513
+ this.analytics?.onStop();
9514
+ });
9508
9515
  }
9509
9516
  if (!this.crossdomainMode) {
9510
9517
  // no need to send iframe viewport data since its a node for us