@openreplay/tracker 3.6.3 → 3.6.6

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.
Files changed (95) hide show
  1. package/.eslintignore +8 -0
  2. package/cjs/app/guards.js +1 -2
  3. package/cjs/app/index.d.ts +15 -13
  4. package/cjs/app/index.js +58 -42
  5. package/cjs/app/logger.js +6 -3
  6. package/cjs/app/observer/iframe_observer.d.ts +1 -1
  7. package/cjs/app/observer/iframe_observer.js +1 -1
  8. package/cjs/app/observer/observer.d.ts +2 -3
  9. package/cjs/app/observer/observer.js +38 -40
  10. package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
  11. package/cjs/app/observer/shadow_root_observer.js +1 -1
  12. package/cjs/app/observer/top_observer.d.ts +2 -2
  13. package/cjs/app/observer/top_observer.js +12 -11
  14. package/cjs/app/sanitizer.d.ts +1 -1
  15. package/cjs/app/sanitizer.js +5 -5
  16. package/cjs/app/session.d.ts +14 -2
  17. package/cjs/app/session.js +19 -6
  18. package/cjs/app/ticker.d.ts +1 -1
  19. package/cjs/common/messages.d.ts +1 -1
  20. package/cjs/common/messages.js +69 -120
  21. package/cjs/common/webworker.d.ts +3 -3
  22. package/cjs/index.d.ts +9 -8
  23. package/cjs/index.js +34 -28
  24. package/cjs/modules/connection.d.ts +1 -1
  25. package/cjs/modules/console.d.ts +1 -1
  26. package/cjs/modules/console.js +5 -5
  27. package/cjs/modules/cssrules.d.ts +1 -1
  28. package/cjs/modules/cssrules.js +3 -3
  29. package/cjs/modules/exception.d.ts +2 -2
  30. package/cjs/modules/exception.js +7 -6
  31. package/cjs/modules/img.d.ts +1 -1
  32. package/cjs/modules/img.js +15 -12
  33. package/cjs/modules/input.d.ts +1 -1
  34. package/cjs/modules/input.js +15 -15
  35. package/cjs/modules/longtasks.d.ts +1 -1
  36. package/cjs/modules/longtasks.js +13 -5
  37. package/cjs/modules/mouse.d.ts +1 -1
  38. package/cjs/modules/mouse.js +10 -12
  39. package/cjs/modules/performance.d.ts +1 -1
  40. package/cjs/modules/scroll.d.ts +1 -1
  41. package/cjs/modules/timing.d.ts +1 -1
  42. package/cjs/modules/timing.js +12 -24
  43. package/cjs/modules/viewport.d.ts +1 -1
  44. package/cjs/utils.js +7 -7
  45. package/cjs/vendors/finder/finder.js +53 -48
  46. package/lib/app/guards.js +1 -2
  47. package/lib/app/index.d.ts +15 -13
  48. package/lib/app/index.js +67 -51
  49. package/lib/app/logger.js +6 -3
  50. package/lib/app/observer/iframe_observer.d.ts +1 -1
  51. package/lib/app/observer/iframe_observer.js +3 -3
  52. package/lib/app/observer/observer.d.ts +2 -3
  53. package/lib/app/observer/observer.js +40 -42
  54. package/lib/app/observer/shadow_root_observer.d.ts +1 -1
  55. package/lib/app/observer/shadow_root_observer.js +3 -3
  56. package/lib/app/observer/top_observer.d.ts +2 -2
  57. package/lib/app/observer/top_observer.js +17 -16
  58. package/lib/app/sanitizer.d.ts +1 -1
  59. package/lib/app/sanitizer.js +7 -7
  60. package/lib/app/session.d.ts +14 -2
  61. package/lib/app/session.js +19 -6
  62. package/lib/app/ticker.d.ts +1 -1
  63. package/lib/common/messages.d.ts +1 -1
  64. package/lib/common/messages.js +69 -120
  65. package/lib/common/tsconfig.tsbuildinfo +1 -1
  66. package/lib/common/webworker.d.ts +3 -3
  67. package/lib/index.d.ts +9 -8
  68. package/lib/index.js +49 -43
  69. package/lib/modules/connection.d.ts +1 -1
  70. package/lib/modules/connection.js +1 -1
  71. package/lib/modules/console.d.ts +1 -1
  72. package/lib/modules/console.js +8 -8
  73. package/lib/modules/cssrules.d.ts +1 -1
  74. package/lib/modules/cssrules.js +5 -5
  75. package/lib/modules/exception.d.ts +2 -2
  76. package/lib/modules/exception.js +8 -7
  77. package/lib/modules/img.d.ts +1 -1
  78. package/lib/modules/img.js +18 -15
  79. package/lib/modules/input.d.ts +1 -1
  80. package/lib/modules/input.js +18 -18
  81. package/lib/modules/longtasks.d.ts +1 -1
  82. package/lib/modules/longtasks.js +14 -6
  83. package/lib/modules/mouse.d.ts +1 -1
  84. package/lib/modules/mouse.js +14 -16
  85. package/lib/modules/performance.d.ts +1 -1
  86. package/lib/modules/performance.js +2 -2
  87. package/lib/modules/scroll.d.ts +1 -1
  88. package/lib/modules/scroll.js +2 -2
  89. package/lib/modules/timing.d.ts +1 -1
  90. package/lib/modules/timing.js +15 -27
  91. package/lib/modules/viewport.d.ts +1 -1
  92. package/lib/modules/viewport.js +1 -1
  93. package/lib/utils.js +7 -7
  94. package/lib/vendors/finder/finder.js +53 -48
  95. package/package.json +28 -10
package/lib/app/index.js CHANGED
@@ -1,14 +1,14 @@
1
- import { Timestamp, Metadata, UserID } from "../common/messages.js";
2
- import { timestamp } from "../utils.js";
3
- import Nodes from "./nodes.js";
4
- import Observer from "./observer/top_observer.js";
5
- import Sanitizer from "./sanitizer.js";
6
- import Ticker from "./ticker.js";
7
- import Logger, { LogLevel } from "./logger.js";
8
- import Session from "./session.js";
9
- import { deviceMemory, jsHeapSizeLimit } from "../modules/performance.js";
10
- const CANCELED = "canceled";
11
- const START_ERROR = ":(";
1
+ import { Timestamp, Metadata, UserID } from '../common/messages.js';
2
+ import { timestamp } from '../utils.js';
3
+ import Nodes from './nodes.js';
4
+ import Observer from './observer/top_observer.js';
5
+ import Sanitizer from './sanitizer.js';
6
+ import Ticker from './ticker.js';
7
+ import Logger, { LogLevel } from './logger.js';
8
+ import Session from './session.js';
9
+ import { deviceMemory, jsHeapSizeLimit } from '../modules/performance.js';
10
+ const CANCELED = 'canceled';
11
+ const START_ERROR = ':(';
12
12
  const UnsuccessfulStart = (reason) => ({ reason, success: false });
13
13
  const SuccessfulStart = (body) => (Object.assign(Object.assign({}, body), { success: true }));
14
14
  var ActivityState;
@@ -29,7 +29,7 @@ export default class App {
29
29
  this.stopCallbacks = [];
30
30
  this.commitCallbacks = [];
31
31
  this.activityState = ActivityState.NotActive;
32
- this.version = '3.6.3'; // TODO: version compatability check inside each plugin.
32
+ this.version = '3.6.6'; // TODO: version compatability check inside each plugin.
33
33
  this.projectKey = projectKey;
34
34
  this.options = Object.assign({
35
35
  revID: '',
@@ -54,9 +54,10 @@ export default class App {
54
54
  this.ticker.attach(() => this.commit());
55
55
  this.debug = new Logger(this.options.__debug__);
56
56
  this.notify = new Logger(this.options.verbose ? LogLevel.Warnings : LogLevel.Silent);
57
- this.session = new Session();
57
+ this.session = new Session(this, this.options);
58
58
  this.session.attachUpdateCallback(({ userID, metadata }) => {
59
- if (userID != null) { // TODO: nullable userID
59
+ if (userID != null) {
60
+ // TODO: nullable userID
60
61
  this.send(new UserID(userID));
61
62
  }
62
63
  if (metadata != null) {
@@ -69,18 +70,17 @@ export default class App {
69
70
  this.sessionStorage.setItem(this.options.session_token_key, sessionToken);
70
71
  }
71
72
  try {
72
- this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function i(...i){return new t(...i)}return i.prototype=t.prototype,i}const i=new Map;const s=t(class{constructor(t,i,s){this.pageNo=t,this.firstIndex=i,this.timestamp=s,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});i.set(80,s);const e=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});i.set(0,e);const n=t(class{constructor(t,i,s){this.url=t,this.referrer=i,this.navigationStart=s,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});i.set(4,n);const r=t(class{constructor(t,i){this.width=t,this.height=i,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});i.set(5,r);const h=t(class{constructor(t,i){this.x=t,this.y=i,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});i.set(6,h);const o=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});i.set(7,o);const c=t(class{constructor(t,i,s,e,n){this.id=t,this.parentID=i,this.index=s,this.tag=e,this.svg=n,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});i.set(8,c);const a=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(9,a);const u=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(10,u);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});i.set(11,d);const l=t(class{constructor(t,i,s){this.id=t,this.name=i,this.value=s,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});i.set(12,l);const p=t(class{constructor(t,i){this.id=t,this.name=i,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});i.set(13,p);const g=t(class{constructor(t,i){this.id=t,this.data=i,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});i.set(14,g);const m=t(class{constructor(t,i,s){this.id=t,this.x=i,this.y=s,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});i.set(16,m);const f=t(class{constructor(t,i){this.id=t,this.label=i,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});i.set(17,f);const y=t(class{constructor(t,i,s){this.id=t,this.value=i,this.mask=s,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});i.set(18,y);const _=t(class{constructor(t,i){this.id=t,this.checked=i,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});i.set(19,_);const v=t(class{constructor(t,i){this.x=t,this.y=i,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});i.set(20,v);const S=t(class{constructor(t,i){this.level=t,this.value=i,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});i.set(22,S);const b=t(class{constructor(t,i,s,e,n,r,h,o,c){this.requestStart=t,this.responseStart=i,this.responseEnd=s,this.domContentLoadedEventStart=e,this.domContentLoadedEventEnd=n,this.loadEventStart=r,this.loadEventEnd=h,this.firstPaint=o,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});i.set(23,b);const w=t(class{constructor(t,i,s){this.speedIndex=t,this.visuallyComplete=i,this.timeToInteractive=s,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});i.set(24,w);const E=t(class{constructor(t,i,s){this.name=t,this.message=i,this.payload=s,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});i.set(25,E);const x=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});i.set(27,x);const T=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});i.set(28,T);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});i.set(29,z);const k=t(class{constructor(t,i){this.key=t,this.value=i,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});i.set(30,k);const A=t(class{constructor(t,i,s){this.id=t,this.rule=i,this.index=s,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});i.set(37,A);const I=t(class{constructor(t,i){this.id=t,this.index=i,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});i.set(38,I);const L=t(class{constructor(t,i,s,e,n,r,h){this.method=t,this.url=i,this.request=s,this.response=e,this.status=n,this.timestamp=r,this.duration=h,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});i.set(39,L);const C=t(class{constructor(t,i,s,e){this.name=t,this.duration=i,this.args=s,this.result=e,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});i.set(40,C);const M=t(class{constructor(t,i){this.key=t,this.value=i,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});i.set(41,M);const N=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});i.set(42,N);const B=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(44,B);const U=t(class{constructor(t,i){this.mutation=t,this.state=i,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});i.set(45,U);const R=t(class{constructor(t,i){this.type=t,this.payload=i,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});i.set(46,R);const O=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(47,O);const P=t(class{constructor(t,i,s,e){this.operationKind=t,this.operationName=i,this.variables=s,this.response=e,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});i.set(48,P);const q=t(class{constructor(t,i,s,e){this.frames=t,this.ticks=i,this.totalJSHeapSize=s,this.usedJSHeapSize=e,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});i.set(49,q);const D=t(class{constructor(t,i,s,e,n,r,h,o){this.timestamp=t,this.duration=i,this.ttfb=s,this.headerSize=e,this.encodedBodySize=n,this.decodedBodySize=r,this.url=h,this.initiator=o,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});i.set(53,D);const W=t(class{constructor(t,i){this.downlink=t,this.type=i,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});i.set(54,W);const H=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});i.set(55,H);const J=t(class{constructor(t,i,s,e,n,r,h){this.timestamp=t,this.duration=i,this.context=s,this.containerType=e,this.containerSrc=n,this.containerId=r,this.containerName=h,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});i.set(59,J);const F=t(class{constructor(t,i,s,e){this.id=t,this.name=i,this.value=s,this.baseURL=e,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});i.set(60,F);const X=t(class{constructor(t,i,s){this.id=t,this.data=i,this.baseURL=s,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});i.set(61,X);const G=t(class{constructor(t,i){this.type=t,this.value=i,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});i.set(63,G);const K=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});i.set(64,K);const j=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});i.set(65,j);const Q=t(class{constructor(t,i,s,e){this.id=t,this.rule=i,this.index=s,this.baseURL=e,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});i.set(67,Q);const V=t(class{constructor(t,i,s,e){this.id=t,this.hesitationTime=i,this.label=s,this.selector=e,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});i.set(69,V);const Y=t(class{constructor(t,i){this.frameID=t,this.id=i,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});i.set(70,Y);class Z{constructor(t,i,s,e=10,n=1e3){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i"}authorise(t){this.token=t}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure():(this.attemptsCount++,setTimeout(()=>this.sendBatch(t),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t){this.busy=!0,fetch(this.ingestURL,{body:t,method:"POST",headers:{Authorization:"Bearer "+this.token},keepalive:t.length<65536}).then(i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();if(i.status>=400)return void this.retry(t);this.attemptsCount=0;const s=this.queue.shift();s?this.sendBatch(s):this.busy=!1}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0}}const tt="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(var n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(!((r=t.charCodeAt(h))>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(h+=1,(n=1024*(n-55296)+r-56320+65536)>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class it{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=tt.encode(t),s=i.byteLength;return!(!this.uint(s)||this.offset+s>this.size)&&(this.data.set(i,this.offset),this.offset+=s,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class st{constructor(t,i,s){this.pageNo=t,this.timestamp=i,this.onBatch=s,this.nextIndex=0,this.beaconSize=2e5,this.writer=new it(this.beaconSize),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}prepare(){this.writer.isEmpty()&&new s(this.pageNo,this.nextIndex,this.timestamp).encode(this.writer)}write(t){const i=t.encode(this.writer);return i&&(this.isEmpty=!1,this.writer.checkpoint(),this.nextIndex++),i}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){for(t instanceof e&&(this.timestamp=t.timestamp);!this.write(t);){if(this.finaliseBatch(),this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message."),this.writer.reset(),this.prepare(),void(this.isEmpty=!0);this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.writer=new it(this.beaconSize),this.prepare(),this.isEmpty=!0}}finaliseBatch(){this.isEmpty||(this.onBatch(this.writer.flush()),this.prepare(),this.isEmpty=!0)}clean(){this.writer.reset()}}var et;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(et||(et={}));let nt=null,rt=null;function ht(){rt&&rt.finaliseBatch()}function ot(){et.Stopping,null!==at&&(clearInterval(at),at=null),rt&&(rt.clean(),rt=null),et.NotActive}et.NotActive;let ct,at=null;self.onmessage=({data:t})=>{if(null!=t){if("stop"===t)return ht(),void ot();if(Array.isArray(t)){if(!rt)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const s=rt;t.forEach(t=>{const e=new(i.get(t._id));Object.assign(e,t),e instanceof H&&(e.hidden?ct=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(ct)),s.writeMessage(e)})}else{if("start"===t.type)return et.Starting,nt=new Z(t.ingestPoint,()=>{self.postMessage("restart")},()=>{nt&&(nt.clean(),nt=null),ot(),self.postMessage("failed")},t.connAttemptCount,t.connAttemptGap),rt=new st(t.pageNo,t.timestamp,t=>nt&&nt.push(t)),null===at&&(at=setInterval(ht,1e4)),et.Active;if("auth"===t.type){if(!nt)throw new Error("WebWorker: sender not initialised. Received auth.");if(!rt)throw new Error("WebWorker: writer not initialised. Received auth.");return nt.authorise(t.token),void(t.beaconSizeLimit&&rt.setBeaconSizeLimit(t.beaconSizeLimit))}}}else ht()};
73
- `], { type: 'text/javascript' })));
74
- this.worker.onerror = e => {
75
- this._debug("webworker_error", e);
73
+ this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";function t(t){function i(...i){return new t(...i)}return i.prototype=t.prototype,i}const i=new Map;const s=t(class{constructor(t,i,s){this.pageNo=t,this.firstIndex=i,this.timestamp=s,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});i.set(80,s);const e=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});i.set(0,e);const n=t(class{constructor(t,i,s){this.url=t,this.referrer=i,this.navigationStart=s,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});i.set(4,n);const r=t(class{constructor(t,i){this.width=t,this.height=i,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});i.set(5,r);const h=t(class{constructor(t,i){this.x=t,this.y=i,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});i.set(6,h);const o=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});i.set(7,o);const c=t(class{constructor(t,i,s,e,n){this.id=t,this.parentID=i,this.index=s,this.tag=e,this.svg=n,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});i.set(8,c);const a=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(9,a);const u=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(10,u);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});i.set(11,d);const l=t(class{constructor(t,i,s){this.id=t,this.name=i,this.value=s,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});i.set(12,l);const p=t(class{constructor(t,i){this.id=t,this.name=i,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});i.set(13,p);const g=t(class{constructor(t,i){this.id=t,this.data=i,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});i.set(14,g);const m=t(class{constructor(t,i,s){this.id=t,this.x=i,this.y=s,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});i.set(16,m);const f=t(class{constructor(t,i){this.id=t,this.label=i,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});i.set(17,f);const y=t(class{constructor(t,i,s){this.id=t,this.value=i,this.mask=s,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});i.set(18,y);const _=t(class{constructor(t,i){this.id=t,this.checked=i,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});i.set(19,_);const v=t(class{constructor(t,i){this.x=t,this.y=i,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});i.set(20,v);const S=t(class{constructor(t,i){this.level=t,this.value=i,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});i.set(22,S);const b=t(class{constructor(t,i,s,e,n,r,h,o,c){this.requestStart=t,this.responseStart=i,this.responseEnd=s,this.domContentLoadedEventStart=e,this.domContentLoadedEventEnd=n,this.loadEventStart=r,this.loadEventEnd=h,this.firstPaint=o,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});i.set(23,b);const w=t(class{constructor(t,i,s){this.speedIndex=t,this.visuallyComplete=i,this.timeToInteractive=s,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});i.set(24,w);const E=t(class{constructor(t,i,s){this.name=t,this.message=i,this.payload=s,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});i.set(25,E);const x=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});i.set(27,x);const T=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});i.set(28,T);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});i.set(29,z);const k=t(class{constructor(t,i){this.key=t,this.value=i,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});i.set(30,k);const A=t(class{constructor(t,i,s){this.id=t,this.rule=i,this.index=s,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});i.set(37,A);const I=t(class{constructor(t,i){this.id=t,this.index=i,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});i.set(38,I);const L=t(class{constructor(t,i,s,e,n,r,h){this.method=t,this.url=i,this.request=s,this.response=e,this.status=n,this.timestamp=r,this.duration=h,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});i.set(39,L);const C=t(class{constructor(t,i,s,e){this.name=t,this.duration=i,this.args=s,this.result=e,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});i.set(40,C);const M=t(class{constructor(t,i){this.key=t,this.value=i,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});i.set(41,M);const N=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});i.set(42,N);const B=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(44,B);const U=t(class{constructor(t,i){this.mutation=t,this.state=i,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});i.set(45,U);const R=t(class{constructor(t,i){this.type=t,this.payload=i,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});i.set(46,R);const O=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(47,O);const P=t(class{constructor(t,i,s,e){this.operationKind=t,this.operationName=i,this.variables=s,this.response=e,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});i.set(48,P);const q=t(class{constructor(t,i,s,e){this.frames=t,this.ticks=i,this.totalJSHeapSize=s,this.usedJSHeapSize=e,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});i.set(49,q);const D=t(class{constructor(t,i,s,e,n,r,h,o){this.timestamp=t,this.duration=i,this.ttfb=s,this.headerSize=e,this.encodedBodySize=n,this.decodedBodySize=r,this.url=h,this.initiator=o,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});i.set(53,D);const W=t(class{constructor(t,i){this.downlink=t,this.type=i,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});i.set(54,W);const H=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});i.set(55,H);const J=t(class{constructor(t,i,s,e,n,r,h){this.timestamp=t,this.duration=i,this.context=s,this.containerType=e,this.containerSrc=n,this.containerId=r,this.containerName=h,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});i.set(59,J);const F=t(class{constructor(t,i,s,e){this.id=t,this.name=i,this.value=s,this.baseURL=e,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});i.set(60,F);const X=t(class{constructor(t,i,s){this.id=t,this.data=i,this.baseURL=s,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});i.set(61,X);const G=t(class{constructor(t,i){this.type=t,this.value=i,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});i.set(63,G);const K=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});i.set(64,K);const j=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});i.set(65,j);const Q=t(class{constructor(t,i,s,e){this.id=t,this.rule=i,this.index=s,this.baseURL=e,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});i.set(67,Q);const V=t(class{constructor(t,i,s,e){this.id=t,this.hesitationTime=i,this.label=s,this.selector=e,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});i.set(69,V);const Y=t(class{constructor(t,i){this.frameID=t,this.id=i,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});i.set(70,Y);class Z{constructor(t,i,s,e=10,n=1e3){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i"}authorise(t){this.token=t}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure():(this.attemptsCount++,setTimeout(()=>this.sendBatch(t),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t){this.busy=!0,fetch(this.ingestURL,{body:t,method:"POST",headers:{Authorization:"Bearer "+this.token},keepalive:t.length<65536}).then(i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();if(i.status>=400)return void this.retry(t);this.attemptsCount=0;const s=this.queue.shift();s?this.sendBatch(s):this.busy=!1}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0}}const tt="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(let n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(r=t.charCodeAt(h),!(r>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(n=1024*(n-55296)+r-56320+65536,h+=1,n>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class it{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=tt.encode(t),s=i.byteLength;return!(!this.uint(s)||this.offset+s>this.size)&&(this.data.set(i,this.offset),this.offset+=s,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class st{constructor(t,i,s){this.pageNo=t,this.timestamp=i,this.onBatch=s,this.nextIndex=0,this.beaconSize=2e5,this.writer=new it(this.beaconSize),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}prepare(){this.writer.isEmpty()&&new s(this.pageNo,this.nextIndex,this.timestamp).encode(this.writer)}write(t){const i=t.encode(this.writer);return i&&(this.isEmpty=!1,this.writer.checkpoint(),this.nextIndex++),i}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){for(t instanceof e&&(this.timestamp=t.timestamp);!this.write(t);){if(this.finaliseBatch(),this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message."),this.writer.reset(),this.prepare(),void(this.isEmpty=!0);this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.writer=new it(this.beaconSize),this.prepare(),this.isEmpty=!0}}finaliseBatch(){this.isEmpty||(this.onBatch(this.writer.flush()),this.prepare(),this.isEmpty=!0)}clean(){this.writer.reset()}}var et;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(et||(et={}));let nt=null,rt=null;function ht(){rt&&rt.finaliseBatch()}function ot(){et.Stopping,null!==ut&&(clearInterval(ut),ut=null),rt&&(rt.clean(),rt=null),nt&&(nt.clean(),nt=null),et.NotActive}function ct(){self.postMessage("restart"),ot()}et.NotActive;let at,ut=null;self.onmessage=({data:t})=>{if(null!=t){if("stop"===t)return ht(),void ot();if(Array.isArray(t)){if(!rt)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const s=rt;t.forEach(t=>{const e=new(i.get(t._id));Object.assign(e,t),e instanceof H&&(e.hidden?at=setTimeout(()=>ct(),18e5):clearTimeout(at)),s.writeMessage(e)})}else{if("start"===t.type)return et.Starting,nt=new Z(t.ingestPoint,()=>{ct()},()=>{self.postMessage("failed"),ot()},t.connAttemptCount,t.connAttemptGap),rt=new st(t.pageNo,t.timestamp,t=>nt&&nt.push(t)),null===ut&&(ut=setInterval(ht,1e4)),et.Active;if("auth"===t.type){if(!nt)throw new Error("WebWorker: sender not initialised. Received auth.");if(!rt)throw new Error("WebWorker: writer not initialised. Received auth.");return nt.authorise(t.token),void(t.beaconSizeLimit&&rt.setBeaconSizeLimit(t.beaconSizeLimit))}}}else ht()};'], { type: 'text/javascript' })));
74
+ this.worker.onerror = (e) => {
75
+ this._debug('webworker_error', e);
76
76
  };
77
77
  this.worker.onmessage = ({ data }) => {
78
- if (data === "failed") {
79
- this.stop();
80
- this._debug("worker_failed", {}); // add context (from worker)
78
+ if (data === 'failed') {
79
+ this.stop(false);
80
+ this._debug('worker_failed', {}); // add context (from worker)
81
81
  }
82
- else if (data === "restart") {
83
- this.stop();
82
+ else if (data === 'restart') {
83
+ this.stop(false);
84
84
  this.start({ forceNew: true });
85
85
  }
86
86
  };
@@ -96,7 +96,7 @@ export default class App {
96
96
  this.attachEventListener(document, 'visibilitychange', alertWorker, false);
97
97
  }
98
98
  catch (e) {
99
- this._debug("worker_start", e);
99
+ this._debug('worker_start', e);
100
100
  }
101
101
  }
102
102
  _debug(context, e) {
@@ -106,11 +106,11 @@ export default class App {
106
106
  headers: { 'Content-Type': 'application/json' },
107
107
  body: JSON.stringify({
108
108
  context,
109
- error: `${e}`
110
- })
109
+ error: `${e}`,
110
+ }),
111
111
  });
112
112
  }
113
- this.debug.error("OpenReplay error: ", context, e);
113
+ this.debug.error('OpenReplay error: ', context, e);
114
114
  }
115
115
  send(message, urgent = false) {
116
116
  if (this.activityState === ActivityState.NotActive) {
@@ -129,7 +129,7 @@ export default class App {
129
129
  if (this.worker && this.messages.length) {
130
130
  this.messages.unshift(new Timestamp(timestamp()));
131
131
  this.worker.postMessage(this.messages);
132
- this.commitCallbacks.forEach(cb => cb(this.messages));
132
+ this.commitCallbacks.forEach((cb) => cb(this.messages));
133
133
  this.messages.length = 0;
134
134
  }
135
135
  }
@@ -140,7 +140,7 @@ export default class App {
140
140
  fn.apply(this, args);
141
141
  }
142
142
  catch (e) {
143
- app._debug("safe_fn_call", e);
143
+ app._debug('safe_fn_call', e);
144
144
  // time: timestamp(),
145
145
  // name: e.name,
146
146
  // message: e.message,
@@ -169,10 +169,13 @@ export default class App {
169
169
  const reqVer = version.split(/[.-]/);
170
170
  const ver = this.version.split(/[.-]/);
171
171
  for (let i = 0; i < 3; i++) {
172
+ if (isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
173
+ return false;
174
+ }
172
175
  if (Number(ver[i]) > Number(reqVer[i])) {
173
176
  return true;
174
177
  }
175
- if (Number(ver[i]) < Number(reqVer[i]) || isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
178
+ if (Number(ver[i]) < Number(reqVer[i])) {
176
179
  return false;
177
180
  }
178
181
  }
@@ -200,6 +203,14 @@ export default class App {
200
203
  getSessionID() {
201
204
  return this.session.getInfo().sessionID || undefined;
202
205
  }
206
+ getSessionURL() {
207
+ const { projectID, sessionID } = this.session.getInfo();
208
+ if (!projectID || !sessionID) {
209
+ this.debug.error('OpenReplay error: Unable to build session URL');
210
+ return undefined;
211
+ }
212
+ return this.options.ingestPoint.replace(/ingest$/, `${projectID}/session/${sessionID}`);
213
+ }
203
214
  getHost() {
204
215
  return new URL(this.options.ingestPoint).hostname;
205
216
  }
@@ -218,12 +229,13 @@ export default class App {
218
229
  return document.baseURI;
219
230
  }
220
231
  // IE only
221
- return ((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName("base")[0]) === null || _b === void 0 ? void 0 : _b.getAttribute("href")) || location.origin + location.pathname;
232
+ return (((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName('base')[0]) === null || _b === void 0 ? void 0 : _b.getAttribute('href')) ||
233
+ location.origin + location.pathname);
222
234
  }
223
235
  resolveResourceURL(resourceURL) {
224
236
  const base = new URL(this.getBaseHref());
225
- base.pathname += "/" + new URL(resourceURL).pathname;
226
- base.pathname.replace(/\/+/g, "/");
237
+ base.pathname += '/' + new URL(resourceURL).pathname;
238
+ base.pathname.replace(/\/+/g, '/');
227
239
  return base.toString();
228
240
  }
229
241
  isServiceURL(url) {
@@ -242,10 +254,10 @@ export default class App {
242
254
  }
243
255
  _start(startOpts) {
244
256
  if (!this.worker) {
245
- return Promise.resolve(UnsuccessfulStart("No worker found: perhaps, CSP is not set."));
257
+ return Promise.resolve(UnsuccessfulStart('No worker found: perhaps, CSP is not set.'));
246
258
  }
247
259
  if (this.activityState !== ActivityState.NotActive) {
248
- return Promise.resolve(UnsuccessfulStart("OpenReplay: trying to call `start()` on the instance that has been started already."));
260
+ return Promise.resolve(UnsuccessfulStart('OpenReplay: trying to call `start()` on the instance that has been started already.'));
249
261
  }
250
262
  this.activityState = ActivityState.Starting;
251
263
  let pageNo = 0;
@@ -257,7 +269,7 @@ export default class App {
257
269
  this.sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
258
270
  const startInfo = this.getStartInfo();
259
271
  const startWorkerMsg = {
260
- type: "start",
272
+ type: 'start',
261
273
  pageNo,
262
274
  ingestPoint: this.options.ingestPoint,
263
275
  timestamp: startInfo.timestamp,
@@ -266,6 +278,7 @@ export default class App {
266
278
  };
267
279
  this.worker.postMessage(startWorkerMsg);
268
280
  this.session.update({
281
+ // TODO: transparent "session" module logic AND explicit internal api for plugins.
269
282
  // "updating" with old metadata in order to trigger session's UpdateCallbacks.
270
283
  // (for the case of internal .start() calls, like on "restart" webworker signal or assistent connection in tracker-assist )
271
284
  metadata: startOpts.metadata || this.session.getInfo().metadata,
@@ -273,7 +286,8 @@ export default class App {
273
286
  });
274
287
  const sReset = this.sessionStorage.getItem(this.options.session_reset_key);
275
288
  this.sessionStorage.removeItem(this.options.session_reset_key);
276
- return window.fetch(this.options.ingestPoint + '/v1/web/start', {
289
+ return window
290
+ .fetch(this.options.ingestPoint + '/v1/web/start', {
277
291
  method: 'POST',
278
292
  headers: {
279
293
  'Content-Type': 'application/json',
@@ -281,19 +295,21 @@ export default class App {
281
295
  body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { userID: this.session.getInfo().userID, token: this.sessionStorage.getItem(this.options.session_token_key), deviceMemory,
282
296
  jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
283
297
  })
284
- .then(r => {
298
+ .then((r) => {
285
299
  if (r.status === 200) {
286
300
  return r.json();
287
301
  }
288
302
  else {
289
- return r.text().then(text => text === CANCELED
303
+ return r
304
+ .text()
305
+ .then((text) => text === CANCELED
290
306
  ? Promise.reject(CANCELED)
291
307
  : Promise.reject(`Server error: ${r.status}. ${text}`));
292
308
  }
293
309
  })
294
- .then(r => {
310
+ .then((r) => {
295
311
  if (!this.worker) {
296
- return Promise.reject("no worker found after start request (this might not happen)");
312
+ return Promise.reject('no worker found after start request (this might not happen)');
297
313
  }
298
314
  const { token, userUUID, sessionID, beaconSizeLimit } = r;
299
315
  if (typeof token !== 'string' ||
@@ -305,9 +321,9 @@ export default class App {
305
321
  this.localStorage.setItem(this.options.local_uuid_key, userUUID);
306
322
  this.session.update({ sessionID }); // TODO: no no-explicit 'any'
307
323
  const startWorkerMsg = {
308
- type: "auth",
324
+ type: 'auth',
309
325
  token,
310
- beaconSizeLimit
326
+ beaconSizeLimit,
311
327
  };
312
328
  this.worker.postMessage(startWorkerMsg);
313
329
  this.activityState = ActivityState.Active;
@@ -315,21 +331,21 @@ export default class App {
315
331
  this.startCallbacks.forEach((cb) => cb(onStartInfo)); // TODO: start as early as possible (before receiving the token)
316
332
  this.observer.observe();
317
333
  this.ticker.start();
318
- this.notify.log("OpenReplay tracking started.");
334
+ this.notify.log('OpenReplay tracking started.');
319
335
  // get rid of onStart ?
320
336
  if (typeof this.options.onStart === 'function') {
321
337
  this.options.onStart(onStartInfo);
322
338
  }
323
339
  return SuccessfulStart(onStartInfo);
324
340
  })
325
- .catch(reason => {
341
+ .catch((reason) => {
326
342
  this.sessionStorage.removeItem(this.options.session_token_key);
327
343
  this.stop();
328
344
  if (reason === CANCELED) {
329
345
  return UnsuccessfulStart(CANCELED);
330
346
  }
331
- this.notify.log("OpenReplay was unable to start. ", reason);
332
- this._debug("session_start", reason);
347
+ this.notify.log('OpenReplay was unable to start. ', reason);
348
+ this._debug('session_start', reason);
333
349
  return UnsuccessfulStart(START_ERROR);
334
350
  });
335
351
  }
@@ -341,11 +357,11 @@ export default class App {
341
357
  return new Promise((resolve) => {
342
358
  const onVisibilityChange = () => {
343
359
  if (!document.hidden) {
344
- document.removeEventListener("visibilitychange", onVisibilityChange);
360
+ document.removeEventListener('visibilitychange', onVisibilityChange);
345
361
  resolve(this._start(options));
346
362
  }
347
363
  };
348
- document.addEventListener("visibilitychange", onVisibilityChange);
364
+ document.addEventListener('visibilitychange', onVisibilityChange);
349
365
  });
350
366
  }
351
367
  }
@@ -360,9 +376,9 @@ export default class App {
360
376
  if (calledFromAPI) {
361
377
  this.session.reset();
362
378
  }
363
- this.notify.log("OpenReplay tracking stopped.");
379
+ this.notify.log('OpenReplay tracking stopped.');
364
380
  if (this.worker && !restarting) {
365
- this.worker.postMessage("stop");
381
+ this.worker.postMessage('stop');
366
382
  }
367
383
  }
368
384
  finally {
package/lib/app/logger.js CHANGED
@@ -10,9 +10,12 @@ function IsCustomLevel(l) {
10
10
  }
11
11
  export default class Logger {
12
12
  constructor(options = LogLevel.Silent) {
13
- this.options = options === true
14
- ? { level: LogLevel.Verbose }
15
- : typeof options === "number" ? { level: options } : options;
13
+ this.options =
14
+ options === true
15
+ ? { level: LogLevel.Verbose }
16
+ : typeof options === 'number'
17
+ ? { level: options }
18
+ : options;
16
19
  }
17
20
  log(...args) {
18
21
  if (IsCustomLevel(this.options.level)
@@ -1,4 +1,4 @@
1
- import Observer from "./observer.js";
1
+ import Observer from './observer.js';
2
2
  export default class IFrameObserver extends Observer {
3
3
  observe(iframe: HTMLIFrameElement): void;
4
4
  }
@@ -1,5 +1,5 @@
1
- import Observer from "./observer.js";
2
- import { CreateIFrameDocument } from "../../common/messages.js";
1
+ import Observer from './observer.js';
2
+ import { CreateIFrameDocument } from '../../common/messages.js';
3
3
  export default class IFrameObserver extends Observer {
4
4
  observe(iframe) {
5
5
  const doc = iframe.contentDocument;
@@ -10,7 +10,7 @@ export default class IFrameObserver extends Observer {
10
10
  // Have to observe document, because the inner <html> might be changed
11
11
  this.observeRoot(doc, (docID) => {
12
12
  if (docID === undefined) {
13
- console.log("OpenReplay: Iframe document not bound");
13
+ console.log('OpenReplay: Iframe document not bound');
14
14
  return;
15
15
  }
16
16
  this.app.send(CreateIFrameDocument(hostID, docID));
@@ -1,4 +1,4 @@
1
- import App from "../index.js";
1
+ import App from '../index.js';
2
2
  export default abstract class Observer {
3
3
  protected readonly app: App;
4
4
  protected readonly isTopContext: boolean;
@@ -13,9 +13,8 @@ export default abstract class Observer {
13
13
  private sendNodeAttribute;
14
14
  private sendNodeData;
15
15
  private bindNode;
16
- private unbindChildNode;
17
16
  private bindTree;
18
- private unbindNode;
17
+ private unbindTree;
19
18
  private _commitNode;
20
19
  private commitNode;
21
20
  private commitNodes;
@@ -1,5 +1,5 @@
1
- import { RemoveNodeAttribute, SetNodeAttribute, SetNodeAttributeURLBased, SetCSSDataURLBased, SetNodeData, CreateTextNode, CreateElementNode, MoveNode, RemoveNode, } from "../../common/messages.js";
2
- import { isRootNode, isTextNode, isElementNode, isSVGElement, hasTag, } from "../guards.js";
1
+ import { RemoveNodeAttribute, SetNodeAttribute, SetNodeAttributeURLBased, SetCSSDataURLBased, SetNodeData, CreateTextNode, CreateElementNode, MoveNode, RemoveNode, } from '../../common/messages.js';
2
+ import { isRootNode, isTextNode, isElementNode, isSVGElement, hasTag } from '../guards.js';
3
3
  function isIgnored(node) {
4
4
  if (isTextNode(node)) {
5
5
  return false;
@@ -11,13 +11,9 @@ function isIgnored(node) {
11
11
  if (tag === 'LINK') {
12
12
  const rel = node.getAttribute('rel');
13
13
  const as = node.getAttribute('as');
14
- return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === "style" || as === "font");
14
+ return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === 'style' || as === 'font');
15
15
  }
16
- return (tag === 'SCRIPT' ||
17
- tag === 'NOSCRIPT' ||
18
- tag === 'META' ||
19
- tag === 'TITLE' ||
20
- tag === 'BASE');
16
+ return (tag === 'SCRIPT' || tag === 'NOSCRIPT' || tag === 'META' || tag === 'TITLE' || tag === 'BASE');
21
17
  }
22
18
  function isObservable(node) {
23
19
  if (isRootNode(node)) {
@@ -30,17 +26,11 @@ function isObservable(node) {
30
26
  - fix unbinding logic + send all removals first (ensure sequence is correct)
31
27
  - use document as a 0-node in the upper context (should be updated in player at first)
32
28
  */
33
- /*
34
- Nikita:
35
- - rn we only send unbind event for parent (all child nodes will be cut in the live replay anyways)
36
- to prevent sending 1k+ unbinds for child nodes and making replay file bigger than it should be
37
- */
38
29
  var RecentsType;
39
30
  (function (RecentsType) {
40
31
  RecentsType[RecentsType["New"] = 0] = "New";
41
32
  RecentsType[RecentsType["Removed"] = 1] = "Removed";
42
33
  RecentsType[RecentsType["Changed"] = 2] = "Changed";
43
- RecentsType[RecentsType["RemovedChild"] = 3] = "RemovedChild";
44
34
  })(RecentsType || (RecentsType = {}));
45
35
  export default class Observer {
46
36
  constructor(app, isTopContext = false) {
@@ -52,7 +42,8 @@ export default class Observer {
52
42
  this.attributesMap = new Map();
53
43
  this.textSet = new Set();
54
44
  this.observer = new MutationObserver(this.app.safe((mutations) => {
55
- for (const mutation of mutations) { // mutations order is sequential
45
+ for (const mutation of mutations) {
46
+ // mutations order is sequential
56
47
  const target = mutation.target;
57
48
  const type = mutation.type;
58
49
  if (!isObservable(target)) {
@@ -60,7 +51,10 @@ export default class Observer {
60
51
  }
61
52
  if (type === 'childList') {
62
53
  for (let i = 0; i < mutation.removedNodes.length; i++) {
63
- this.bindTree(mutation.removedNodes[i], true);
54
+ // Should be the same as bindTree(mutation.removedNodes[i]), but logic needs to be be untied
55
+ if (isObservable(mutation.removedNodes[i])) {
56
+ this.bindNode(mutation.removedNodes[i]);
57
+ }
64
58
  }
65
59
  for (let i = 0; i < mutation.addedNodes.length; i++) {
66
60
  this.bindTree(mutation.addedNodes[i]);
@@ -81,7 +75,7 @@ export default class Observer {
81
75
  }
82
76
  let attr = this.attributesMap.get(id);
83
77
  if (attr === undefined) {
84
- this.attributesMap.set(id, attr = new Set());
78
+ this.attributesMap.set(id, (attr = new Set()));
85
79
  }
86
80
  attr.add(name);
87
81
  continue;
@@ -129,7 +123,7 @@ export default class Observer {
129
123
  return;
130
124
  }
131
125
  if (name === 'value' &&
132
- hasTag(node, "INPUT") &&
126
+ hasTag(node, 'INPUT') &&
133
127
  node.type !== 'button' &&
134
128
  node.type !== 'reset' &&
135
129
  node.type !== 'submit') {
@@ -139,7 +133,7 @@ export default class Observer {
139
133
  this.app.send(new RemoveNodeAttribute(id, name));
140
134
  return;
141
135
  }
142
- if (name === 'style' || name === 'href' && hasTag(node, "LINK")) {
136
+ if (name === 'style' || (name === 'href' && hasTag(node, 'LINK'))) {
143
137
  this.app.send(new SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
144
138
  return;
145
139
  }
@@ -149,7 +143,7 @@ export default class Observer {
149
143
  this.app.send(new SetNodeAttribute(id, name, value));
150
144
  }
151
145
  sendNodeData(id, parentElement, data) {
152
- if (hasTag(parentElement, "STYLE") || hasTag(parentElement, "style")) {
146
+ if (hasTag(parentElement, 'STYLE') || hasTag(parentElement, 'style')) {
153
147
  this.app.send(new SetCSSDataURLBased(id, data, this.app.getBaseHref()));
154
148
  return;
155
149
  }
@@ -161,40 +155,43 @@ export default class Observer {
161
155
  if (isNew) {
162
156
  this.recents.set(id, RecentsType.New);
163
157
  }
164
- else if (this.recents.get(id) !== RecentsType.New) { // can we do just `else` here?
158
+ else if (this.recents.get(id) !== RecentsType.New) {
165
159
  this.recents.set(id, RecentsType.Removed);
166
160
  }
167
161
  }
168
- unbindChildNode(node) {
169
- const [id] = this.app.nodes.registerNode(node);
170
- this.recents.set(id, RecentsType.RemovedChild);
171
- }
172
- bindTree(node, isChildUnbinding = false) {
162
+ bindTree(node) {
173
163
  if (!isObservable(node)) {
174
164
  return;
175
165
  }
176
166
  this.bindNode(node);
177
167
  const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
178
- acceptNode: (node) => isIgnored(node)
179
- || (this.app.nodes.getID(node) !== undefined && !isChildUnbinding)
168
+ acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) !== undefined
180
169
  ? NodeFilter.FILTER_REJECT
181
170
  : NodeFilter.FILTER_ACCEPT,
182
171
  },
183
172
  // @ts-ignore
184
173
  false);
185
174
  while (walker.nextNode()) {
186
- if (isChildUnbinding) {
187
- this.unbindChildNode(walker.currentNode);
188
- }
189
- else {
190
- this.bindNode(walker.currentNode);
191
- }
175
+ this.bindNode(walker.currentNode);
192
176
  }
193
177
  }
194
- unbindNode(node) {
178
+ unbindTree(node) {
195
179
  const id = this.app.nodes.unregisterNode(node);
196
180
  if (id !== undefined && this.recents.get(id) === RecentsType.Removed) {
197
- this.app.send(new RemoveNode(id));
181
+ // Sending RemoveNode only for parent to maintain
182
+ this.app.send(RemoveNode(id));
183
+ // Unregistering all the children in order to clear the memory
184
+ const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
185
+ acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) === undefined
186
+ ? NodeFilter.FILTER_REJECT
187
+ : NodeFilter.FILTER_ACCEPT,
188
+ },
189
+ // @ts-ignore
190
+ false);
191
+ while (walker.nextNode()) {
192
+ this.app.nodes.unregisterNode(walker.currentNode);
193
+ }
194
+ // MBTODO: count and send RemovedNodesCount (for the page crash detection in heuristics)
198
195
  }
199
196
  }
200
197
  // A top-consumption function on the infinite lists test. (~1% of performance resources)
@@ -207,20 +204,20 @@ export default class Observer {
207
204
  // Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
208
205
  // TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
209
206
  // TODO: Clean the logic (though now it workd fine)
210
- if (!hasTag(node, "HTML") || !this.isTopContext) {
207
+ if (!hasTag(node, 'HTML') || !this.isTopContext) {
211
208
  if (parent === null) {
212
209
  // Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
213
- // That shouldn't affect the visual rendering ( should it? )
214
- this.unbindNode(node);
210
+ // That shouldn't affect the visual rendering ( should it? maybe when transition applied? )
211
+ this.unbindTree(node);
215
212
  return false;
216
213
  }
217
214
  parentID = this.app.nodes.getID(parent);
218
215
  if (parentID === undefined) {
219
- this.unbindNode(node);
216
+ this.unbindTree(node);
220
217
  return false;
221
218
  }
222
219
  if (!this.commitNode(parentID)) {
223
- this.unbindNode(node);
220
+ this.unbindTree(node);
224
221
  return false;
225
222
  }
226
223
  this.app.sanitizer.handleNode(id, parentID, node);
@@ -315,7 +312,8 @@ export default class Observer {
315
312
  });
316
313
  this.clear();
317
314
  }
318
- // ISSSUE
315
+ // ISSSUE (nodeToBinde should be the same as node. Look at the comment about 0-node at the beginning of the file.)
316
+ // TODO: use one observer instance for all iframes/shadowRoots (composition instiad of inheritance)
319
317
  observeRoot(node, beforeCommit, nodeToBind = node) {
320
318
  this.observer.observe(node, {
321
319
  childList: true,
@@ -1,4 +1,4 @@
1
- import Observer from "./observer.js";
1
+ import Observer from './observer.js';
2
2
  export default class ShadowRootObserver extends Observer {
3
3
  observe(el: Element): void;
4
4
  }
@@ -1,5 +1,5 @@
1
- import Observer from "./observer.js";
2
- import { CreateIFrameDocument } from "../../common/messages.js";
1
+ import Observer from './observer.js';
2
+ import { CreateIFrameDocument } from '../../common/messages.js';
3
3
  export default class ShadowRootObserver extends Observer {
4
4
  observe(el) {
5
5
  const shRoot = el.shadowRoot;
@@ -9,7 +9,7 @@ export default class ShadowRootObserver extends Observer {
9
9
  } // log
10
10
  this.observeRoot(shRoot, (rootID) => {
11
11
  if (rootID === undefined) {
12
- console.log("OpenReplay: Shadow Root was not bound");
12
+ console.log('OpenReplay: Shadow Root was not bound');
13
13
  return;
14
14
  }
15
15
  this.app.send(CreateIFrameDocument(hostID, rootID));
@@ -1,5 +1,5 @@
1
- import Observer from "./observer.js";
2
- import App from "../index.js";
1
+ import Observer from './observer.js';
2
+ import App from '../index.js';
3
3
  export interface Options {
4
4
  captureIFrames: boolean;
5
5
  }