@openreplay/tracker 3.4.16 → 3.5.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.
Files changed (48) hide show
  1. package/README.md +8 -1
  2. package/cjs/app/context.d.ts +18 -0
  3. package/cjs/app/context.js +48 -0
  4. package/cjs/app/index.d.ts +39 -9
  5. package/cjs/app/index.js +155 -121
  6. package/cjs/app/logger.d.ts +27 -0
  7. package/cjs/app/logger.js +42 -0
  8. package/cjs/app/observer/observer.d.ts +2 -27
  9. package/cjs/app/observer/observer.js +18 -92
  10. package/cjs/app/observer/top_observer.d.ts +3 -3
  11. package/cjs/app/observer/top_observer.js +11 -8
  12. package/cjs/app/sanitizer.d.ts +16 -0
  13. package/cjs/app/sanitizer.js +46 -0
  14. package/cjs/index.d.ts +10 -9
  15. package/cjs/index.js +32 -21
  16. package/cjs/modules/console.js +1 -1
  17. package/cjs/modules/img.js +15 -1
  18. package/cjs/modules/input.d.ts +3 -1
  19. package/cjs/modules/input.js +6 -3
  20. package/cjs/modules/mouse.js +3 -1
  21. package/cjs/utils.d.ts +0 -8
  22. package/cjs/utils.js +3 -4
  23. package/lib/app/context.d.ts +18 -0
  24. package/lib/app/context.js +43 -0
  25. package/lib/app/index.d.ts +39 -9
  26. package/lib/app/index.js +156 -122
  27. package/lib/app/logger.d.ts +27 -0
  28. package/lib/app/logger.js +39 -1
  29. package/lib/app/observer/observer.d.ts +2 -27
  30. package/lib/app/observer/observer.js +7 -79
  31. package/lib/app/observer/top_observer.d.ts +3 -3
  32. package/lib/app/observer/top_observer.js +10 -7
  33. package/lib/app/sanitizer.d.ts +16 -0
  34. package/lib/app/sanitizer.js +44 -1
  35. package/lib/index.d.ts +10 -9
  36. package/lib/index.js +32 -21
  37. package/lib/modules/console.js +1 -1
  38. package/lib/modules/img.js +16 -2
  39. package/lib/modules/input.d.ts +3 -1
  40. package/lib/modules/input.js +6 -3
  41. package/lib/modules/mouse.js +3 -1
  42. package/lib/utils.d.ts +0 -8
  43. package/lib/utils.js +2 -3
  44. package/package.json +1 -1
  45. package/cjs/app/observer.d.ts +0 -47
  46. package/cjs/app/observer.js +0 -395
  47. package/lib/app/observer.d.ts +0 -47
  48. package/lib/app/observer.js +0 -392
package/lib/app/index.js CHANGED
@@ -1,46 +1,61 @@
1
- import { timestamp, log, warn } from "../utils.js";
2
- import { Timestamp } from "../messages/index.js";
1
+ import { timestamp } from "../utils.js";
2
+ import { Timestamp, Metadata } from "../messages/index.js";
3
3
  import Nodes from "./nodes.js";
4
4
  import Observer from "./observer/top_observer.js";
5
+ import Sanitizer from "./sanitizer.js";
5
6
  import Ticker from "./ticker.js";
7
+ import Logger, { LogLevel } from "./logger.js";
6
8
  import { deviceMemory, jsHeapSizeLimit } from "../modules/performance.js";
9
+ var ActivityState;
10
+ (function (ActivityState) {
11
+ ActivityState[ActivityState["NotActive"] = 0] = "NotActive";
12
+ ActivityState[ActivityState["Starting"] = 1] = "Starting";
13
+ ActivityState[ActivityState["Active"] = 2] = "Active";
14
+ })(ActivityState || (ActivityState = {}));
15
+ export const CANCELED = "canceled";
7
16
  // TODO: use backendHost only
8
17
  export const DEFAULT_INGEST_POINT = 'https://api.openreplay.com/ingest';
9
18
  export default class App {
10
- constructor(projectKey, sessionToken, opts) {
19
+ constructor(projectKey, sessionToken, options) {
20
+ // if (options.onStart !== undefined) {
21
+ // deprecationWarn("'onStart' option", "tracker.start().then(/* handle session info */)")
22
+ // } ?? maybe onStart is good
11
23
  this.messages = [];
12
24
  this.startCallbacks = [];
13
25
  this.stopCallbacks = [];
14
26
  this.commitCallbacks = [];
15
27
  this._sessionID = null;
16
- this.isActive = false;
17
- this.version = '3.4.16';
28
+ this._userID = null;
29
+ this._metadata = {};
30
+ this.activityState = ActivityState.NotActive;
31
+ this.version = '3.5.0'; // TODO: version compatability check inside each plugin.
18
32
  this.projectKey = projectKey;
19
33
  this.options = Object.assign({
20
34
  revID: '',
21
35
  node_id: '__openreplay_id',
22
36
  session_token_key: '__openreplay_token',
23
37
  session_pageno_key: '__openreplay_pageno',
38
+ session_reset_key: '__openreplay_reset',
24
39
  local_uuid_key: '__openreplay_uuid',
25
40
  ingestPoint: DEFAULT_INGEST_POINT,
26
41
  resourceBaseHref: null,
42
+ verbose: false,
27
43
  __is_snippet: false,
28
44
  __debug_report_edp: null,
29
- __debug_log: false,
30
- obscureTextEmails: true,
31
- obscureTextNumbers: false,
32
- captureIFrames: false,
33
- }, opts);
45
+ }, options);
34
46
  if (sessionToken != null) {
35
47
  sessionStorage.setItem(this.options.session_token_key, sessionToken);
36
48
  }
37
49
  this.revID = this.options.revID;
50
+ this.sanitizer = new Sanitizer(this, options);
38
51
  this.nodes = new Nodes(this.options.node_id);
39
- this.observer = new Observer(this, this.options);
52
+ this.observer = new Observer(this, options);
40
53
  this.ticker = new Ticker(this);
41
54
  this.ticker.attach(() => this.commit());
55
+ this.debug = new Logger(this.options.__debug__);
56
+ this.notify = new Logger(this.options.verbose ? LogLevel.Warnings : LogLevel.Silent);
42
57
  try {
43
- this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function s(...s){return new t(...s)}return s.prototype=t.prototype,s}const s=new Map;const i=t(class{constructor(t,s,i){this.pageNo=t,this.firstIndex=s,this.timestamp=i,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});s.set(80,i);const n=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});s.set(0,n);const e=t(class{constructor(t,s,i){this.url=t,this.referrer=s,this.navigationStart=i,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});s.set(4,e);const r=t(class{constructor(t,s){this.width=t,this.height=s,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});s.set(5,r);const o=t(class{constructor(t,s){this.x=t,this.y=s,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});s.set(6,o);const h=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});s.set(7,h);const c=t(class{constructor(t,s,i,n,e){this.id=t,this.parentID=s,this.index=i,this.tag=n,this.svg=e,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)}});s.set(8,c);const u=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(9,u);const a=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(10,a);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});s.set(11,d);const l=t(class{constructor(t,s,i){this.id=t,this.name=s,this.value=i,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});s.set(12,l);const g=t(class{constructor(t,s){this.id=t,this.name=s,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});s.set(13,g);const f=t(class{constructor(t,s){this.id=t,this.data=s,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});s.set(14,f);const p=t(class{constructor(t,s,i){this.id=t,this.x=s,this.y=i,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});s.set(16,p);const m=t(class{constructor(t,s){this.id=t,this.label=s,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});s.set(17,m);const _=t(class{constructor(t,s,i){this.id=t,this.value=s,this.mask=i,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});s.set(18,_);const y=t(class{constructor(t,s){this.id=t,this.checked=s,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});s.set(19,y);const v=t(class{constructor(t,s){this.x=t,this.y=s,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});s.set(20,v);const S=t(class{constructor(t,s){this.level=t,this.value=s,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});s.set(22,S);const b=t(class{constructor(t,s,i,n,e,r,o,h,c){this.requestStart=t,this.responseStart=s,this.responseEnd=i,this.domContentLoadedEventStart=n,this.domContentLoadedEventEnd=e,this.loadEventStart=r,this.loadEventEnd=o,this.firstPaint=h,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)}});s.set(23,b);const x=t(class{constructor(t,s,i){this.speedIndex=t,this.visuallyComplete=s,this.timeToInteractive=i,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});s.set(24,x);const E=t(class{constructor(t,s,i){this.name=t,this.message=s,this.payload=i,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});s.set(25,E);const k=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});s.set(27,k);const I=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});s.set(28,I);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});s.set(29,z);const w=t(class{constructor(t,s){this.key=t,this.value=s,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});s.set(30,w);const T=t(class{constructor(t,s,i){this.id=t,this.rule=s,this.index=i,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});s.set(37,T);const L=t(class{constructor(t,s){this.id=t,this.index=s,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});s.set(38,L);const A=t(class{constructor(t,s,i,n,e,r,o){this.method=t,this.url=s,this.request=i,this.response=n,this.status=e,this.timestamp=r,this.duration=o,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)}});s.set(39,A);const C=t(class{constructor(t,s,i,n){this.name=t,this.duration=s,this.args=i,this.result=n,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)}});s.set(40,C);const M=t(class{constructor(t,s){this.key=t,this.value=s,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});s.set(41,M);const R=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});s.set(42,R);const N=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(44,N);const D=t(class{constructor(t,s){this.mutation=t,this.state=s,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});s.set(45,D);const U=t(class{constructor(t,s){this.type=t,this.payload=s,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});s.set(46,U);const O=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(47,O);const q=t(class{constructor(t,s,i,n){this.operationKind=t,this.operationName=s,this.variables=i,this.response=n,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)}});s.set(48,q);const H=t(class{constructor(t,s,i,n){this.frames=t,this.ticks=s,this.totalJSHeapSize=i,this.usedJSHeapSize=n,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)}});s.set(49,H);const P=t(class{constructor(t,s,i,n,e,r,o,h){this.timestamp=t,this.duration=s,this.ttfb=i,this.headerSize=n,this.encodedBodySize=e,this.decodedBodySize=r,this.url=o,this.initiator=h,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)}});s.set(53,P);const B=t(class{constructor(t,s){this.downlink=t,this.type=s,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});s.set(54,B);const J=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});s.set(55,J);const j=t(class{constructor(t,s,i,n,e,r,o){this.timestamp=t,this.duration=s,this.context=i,this.containerType=n,this.containerSrc=e,this.containerId=r,this.containerName=o,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)}});s.set(59,j);const G=t(class{constructor(t,s,i,n){this.id=t,this.name=s,this.value=i,this.baseURL=n,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)}});s.set(60,G);const K=t(class{constructor(t,s,i){this.id=t,this.data=s,this.baseURL=i,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});s.set(61,K);const X=t(class{constructor(t,s){this.type=t,this.value=s,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});s.set(63,X);const F=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});s.set(64,F);const Q=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});s.set(65,Q);const V=t(class{constructor(t,s,i,n){this.id=t,this.rule=s,this.index=i,this.baseURL=n,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)}});s.set(67,V);const W=t(class{constructor(t,s,i,n){this.id=t,this.hesitationTime=s,this.label=i,this.selector=n,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)}});s.set(69,W);const Y=t(class{constructor(t,s){this.frameID=t,this.id=s,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});s.set(70,Y);const Z="function"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let n=-1;for(var e=0,r=0,o=0;o!==s;){if(e=t.charCodeAt(o),o+=1,e>=55296&&e<=56319){if(o===s){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;break}if(!((r=t.charCodeAt(o))>=56320&&r<=57343)){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;continue}if(o+=1,(e=1024*(e-55296)+r-56320+65536)>65535){i[n+=1]=240|e>>>18,i[n+=1]=128|e>>>12&63,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e;continue}}e<=127?i[n+=1]=0|e:e<=2047?(i[n+=1]=192|e>>>6,i[n+=1]=128|63&e):(i[n+=1]=224|e>>>12,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e)}return i.subarray(0,n+1)}};class tt{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 s=Z.encode(t),i=s.byteLength;return!(!this.uint(i)||this.offset+i>this.size)&&(this.data.set(s,this.offset),this.offset+=i,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}let st=1e6,it=2e5,nt=new tt(it),et="",rt="",ot=0,ht=0,ct=0,ut=0,at=!0;function dt(){return new i(ot,ut,ht).encode(nt)}let lt=null;const gt=[];let ft,pt=!1,mt=0,_t=8e3,yt=10;function vt(){if(at||""===rt||""===et)return;const t=nt.flush();pt?gt.push(t):(pt=!0,function t(s){const i=new XMLHttpRequest;i.open("POST",et+"/v1/web/i",!1),i.setRequestHeader("Authorization","Bearer "+rt),i.onreadystatechange=function(){if(4===this.readyState){if(0==this.status)return;if(this.status>=400)return St(),gt.length=0,401===this.status?void self.postMessage("restart"):void self.postMessage(null);const s=gt.shift();s?t(s):pt=!1}},i.onerror=function(i){if(mt>=yt)return St(),void self.postMessage(null);mt++,setTimeout(()=>t(s),_t)},i.send(s.buffer)}(t)),at=!0,dt()}function St(){et="",rt="",null!==lt&&(clearInterval(lt),lt=null),nt.reset()}self.onmessage=({data:t})=>{if(null!==t)return"stop"===t?(vt(),void St()):Array.isArray(t)?void t.forEach(t=>{const i=new(s.get(t._id));if(Object.assign(i,t),i instanceof n?ht=i.timestamp:i instanceof J&&(i.hidden?ft=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(ft)),nt.checkpoint(),!i.encode(nt)&&(vt(),!i.encode(nt)))for(;!i.encode(nt);){if(it===st)return console.warn("OpenReplay: beacon size overflow."),nt.reset(),void dt();it=Math.min(2*it,st),nt=new tt(it),dt()}ut++,at=!1}):(et=t.ingestPoint||et,rt=t.token||rt,ot=t.pageNo||ot,ht=t.startTimestamp||ht,ct=t.timeAdjustment||ct,yt=t.connAttemptCount||yt,_t=t.connAttemptGap||_t,st=t.beaconSizeLimit||st,it=Math.min(st,t.beaconSize||it),nt.isEmpty()&&dt(),void(null===lt&&(lt=setInterval(vt,1e4))));vt()};
58
+ this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function s(...s){return new t(...s)}return s.prototype=t.prototype,s}const s=new Map;const i=t(class{constructor(t,s,i){this.pageNo=t,this.firstIndex=s,this.timestamp=i,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});s.set(80,i);const n=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});s.set(0,n);const e=t(class{constructor(t,s,i){this.url=t,this.referrer=s,this.navigationStart=i,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});s.set(4,e);const r=t(class{constructor(t,s){this.width=t,this.height=s,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});s.set(5,r);const o=t(class{constructor(t,s){this.x=t,this.y=s,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});s.set(6,o);const h=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});s.set(7,h);const c=t(class{constructor(t,s,i,n,e){this.id=t,this.parentID=s,this.index=i,this.tag=n,this.svg=e,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)}});s.set(8,c);const u=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(9,u);const a=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(10,a);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});s.set(11,d);const l=t(class{constructor(t,s,i){this.id=t,this.name=s,this.value=i,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});s.set(12,l);const g=t(class{constructor(t,s){this.id=t,this.name=s,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});s.set(13,g);const f=t(class{constructor(t,s){this.id=t,this.data=s,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});s.set(14,f);const p=t(class{constructor(t,s,i){this.id=t,this.x=s,this.y=i,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});s.set(16,p);const m=t(class{constructor(t,s){this.id=t,this.label=s,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});s.set(17,m);const _=t(class{constructor(t,s,i){this.id=t,this.value=s,this.mask=i,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});s.set(18,_);const y=t(class{constructor(t,s){this.id=t,this.checked=s,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});s.set(19,y);const v=t(class{constructor(t,s){this.x=t,this.y=s,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});s.set(20,v);const S=t(class{constructor(t,s){this.level=t,this.value=s,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});s.set(22,S);const b=t(class{constructor(t,s,i,n,e,r,o,h,c){this.requestStart=t,this.responseStart=s,this.responseEnd=i,this.domContentLoadedEventStart=n,this.domContentLoadedEventEnd=e,this.loadEventStart=r,this.loadEventEnd=o,this.firstPaint=h,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)}});s.set(23,b);const x=t(class{constructor(t,s,i){this.speedIndex=t,this.visuallyComplete=s,this.timeToInteractive=i,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});s.set(24,x);const E=t(class{constructor(t,s,i){this.name=t,this.message=s,this.payload=i,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});s.set(25,E);const k=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});s.set(27,k);const I=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});s.set(28,I);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});s.set(29,z);const w=t(class{constructor(t,s){this.key=t,this.value=s,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});s.set(30,w);const T=t(class{constructor(t,s,i){this.id=t,this.rule=s,this.index=i,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});s.set(37,T);const L=t(class{constructor(t,s){this.id=t,this.index=s,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});s.set(38,L);const A=t(class{constructor(t,s,i,n,e,r,o){this.method=t,this.url=s,this.request=i,this.response=n,this.status=e,this.timestamp=r,this.duration=o,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)}});s.set(39,A);const C=t(class{constructor(t,s,i,n){this.name=t,this.duration=s,this.args=i,this.result=n,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)}});s.set(40,C);const M=t(class{constructor(t,s){this.key=t,this.value=s,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});s.set(41,M);const R=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});s.set(42,R);const N=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(44,N);const D=t(class{constructor(t,s){this.mutation=t,this.state=s,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});s.set(45,D);const U=t(class{constructor(t,s){this.type=t,this.payload=s,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});s.set(46,U);const O=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(47,O);const q=t(class{constructor(t,s,i,n){this.operationKind=t,this.operationName=s,this.variables=i,this.response=n,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)}});s.set(48,q);const H=t(class{constructor(t,s,i,n){this.frames=t,this.ticks=s,this.totalJSHeapSize=i,this.usedJSHeapSize=n,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)}});s.set(49,H);const P=t(class{constructor(t,s,i,n,e,r,o,h){this.timestamp=t,this.duration=s,this.ttfb=i,this.headerSize=n,this.encodedBodySize=e,this.decodedBodySize=r,this.url=o,this.initiator=h,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)}});s.set(53,P);const B=t(class{constructor(t,s){this.downlink=t,this.type=s,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});s.set(54,B);const J=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});s.set(55,J);const j=t(class{constructor(t,s,i,n,e,r,o){this.timestamp=t,this.duration=s,this.context=i,this.containerType=n,this.containerSrc=e,this.containerId=r,this.containerName=o,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)}});s.set(59,j);const G=t(class{constructor(t,s,i,n){this.id=t,this.name=s,this.value=i,this.baseURL=n,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)}});s.set(60,G);const K=t(class{constructor(t,s,i){this.id=t,this.data=s,this.baseURL=i,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});s.set(61,K);const X=t(class{constructor(t,s){this.type=t,this.value=s,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});s.set(63,X);const F=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});s.set(64,F);const Q=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});s.set(65,Q);const V=t(class{constructor(t,s,i,n){this.id=t,this.rule=s,this.index=i,this.baseURL=n,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)}});s.set(67,V);const W=t(class{constructor(t,s,i,n){this.id=t,this.hesitationTime=s,this.label=i,this.selector=n,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)}});s.set(69,W);const Y=t(class{constructor(t,s){this.frameID=t,this.id=s,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});s.set(70,Y);const Z="function"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let n=-1;for(var e=0,r=0,o=0;o!==s;){if(e=t.charCodeAt(o),o+=1,e>=55296&&e<=56319){if(o===s){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;break}if(!((r=t.charCodeAt(o))>=56320&&r<=57343)){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;continue}if(o+=1,(e=1024*(e-55296)+r-56320+65536)>65535){i[n+=1]=240|e>>>18,i[n+=1]=128|e>>>12&63,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e;continue}}e<=127?i[n+=1]=0|e:e<=2047?(i[n+=1]=192|e>>>6,i[n+=1]=128|63&e):(i[n+=1]=224|e>>>12,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e)}return i.subarray(0,n+1)}};class tt{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 s=Z.encode(t),i=s.byteLength;return!(!this.uint(i)||this.offset+i>this.size)&&(this.data.set(s,this.offset),this.offset+=i,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}let st=1e6,it=2e5,nt=new tt(it),et="",rt="",ot=0,ht=0,ct=0,ut=0,at=!0;function dt(){return new i(ot,ut,ht).encode(nt)}let lt=null;const gt=[];let ft,pt=!1,mt=0,_t=8e3,yt=10;function vt(){if(at||""===rt||""===et)return;const t=nt.flush();pt?gt.push(t):(pt=!0,function t(s){const i=new XMLHttpRequest;i.open("POST",et+"/v1/web/i",!1),i.setRequestHeader("Authorization","Bearer "+rt),i.onreadystatechange=function(){if(4===this.readyState){if(0==this.status)return;if(this.status>=400)return pt=!1,St(),gt.length=0,401===this.status?void self.postMessage("restart"):void self.postMessage(null);const s=gt.shift();s?t(s):pt=!1}},i.onerror=function(i){if(mt>=yt)return St(),void self.postMessage(null);mt++,setTimeout(()=>t(s),_t)},i.send(s.buffer)}(t)),at=!0,dt()}function St(){et="",rt="",null!==lt&&(clearInterval(lt),lt=null),nt.reset()}self.onmessage=({data:t})=>{if(null!==t)return"stop"===t?(vt(),void St()):Array.isArray(t)?void t.forEach(t=>{const i=new(s.get(t._id));if(Object.assign(i,t),i instanceof n?ht=i.timestamp:i instanceof J&&(i.hidden?ft=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(ft)),nt.checkpoint(),!i.encode(nt)&&(vt(),!i.encode(nt)))for(;!i.encode(nt);){if(it===st)return console.warn("OpenReplay: beacon size overflow."),nt.reset(),void dt();it=Math.min(2*it,st),nt=new tt(it),dt()}ut++,at=!1}):(et=t.ingestPoint||et,rt=t.token||rt,ot=t.pageNo||ot,ht=t.startTimestamp||ht,ct=t.timeAdjustment||ct,yt=t.connAttemptCount||yt,_t=t.connAttemptGap||_t,st=t.beaconSizeLimit||st,it=Math.min(st,t.beaconSize||it),nt.isEmpty()&&dt(),void(null===lt&&(lt=setInterval(vt,1e4))));vt()};
44
59
  `], { type: 'text/javascript' })));
45
60
  this.worker.onerror = e => {
46
61
  this._debug("webworker_error", e);
@@ -53,7 +68,11 @@ export default class App {
53
68
  }
54
69
  else if (data === "restart") {
55
70
  this.stop();
56
- this.start(true);
71
+ this.start({
72
+ forceNew: true,
73
+ userID: this._userID || undefined,
74
+ metadata: this._metadata || undefined,
75
+ });
57
76
  }
58
77
  };
59
78
  const alertWorker = () => {
@@ -81,12 +100,10 @@ export default class App {
81
100
  })
82
101
  });
83
102
  }
84
- if (this.options.__debug_log) {
85
- warn("OpenReplay error: ", context, e);
86
- }
103
+ this.debug.error("OpenReplay error: ", context, e);
87
104
  }
88
105
  send(message, urgent = false) {
89
- if (!this.isActive) {
106
+ if (this.activityState !== ActivityState.Active) {
90
107
  return;
91
108
  }
92
109
  this.messages.push(message);
@@ -105,10 +122,6 @@ export default class App {
105
122
  attachCommitCallback(cb) {
106
123
  this.commitCallbacks.push(cb);
107
124
  }
108
- // @Depricated (TODO: remove in 3.5.*)
109
- addCommitCallback(cb) {
110
- this.attachCommitCallback(cb);
111
- }
112
125
  safe(fn) {
113
126
  const app = this;
114
127
  return function (...args) {
@@ -137,6 +150,30 @@ export default class App {
137
150
  this.attachStartCallback(() => target.addEventListener(type, listener, useCapture));
138
151
  this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture));
139
152
  }
153
+ checkRequiredVersion(version) {
154
+ const reqVer = version.split('.');
155
+ const ver = this.version.split('.');
156
+ for (let i = 0; i < ver.length; i++) {
157
+ if (Number(ver[i]) < Number(reqVer[i]) || isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
158
+ return false;
159
+ }
160
+ }
161
+ return true;
162
+ }
163
+ getStartInfo() {
164
+ return {
165
+ userUUID: localStorage.getItem(this.options.local_uuid_key),
166
+ projectKey: this.projectKey,
167
+ revID: this.revID,
168
+ timestamp: timestamp(),
169
+ trackerVersion: this.version,
170
+ userID: this._userID,
171
+ isSnippet: this.options.__is_snippet,
172
+ };
173
+ }
174
+ getSessionInfo() {
175
+ return Object.assign({ sessionID: this._sessionID, metadata: this._metadata }, this.getStartInfo());
176
+ }
140
177
  getSessionToken() {
141
178
  const token = sessionStorage.getItem(this.options.session_token_key);
142
179
  if (token !== null) {
@@ -176,116 +213,112 @@ export default class App {
176
213
  return url.startsWith(this.options.ingestPoint);
177
214
  }
178
215
  active() {
179
- return this.isActive;
216
+ return this.activityState === ActivityState.Active;
180
217
  }
181
- _start(reset) {
182
- if (!this.isActive) {
218
+ resetNextPageSession(flag) {
219
+ if (flag) {
220
+ sessionStorage.setItem(this.options.session_reset_key, 't');
221
+ }
222
+ else {
223
+ sessionStorage.removeItem(this.options.session_reset_key);
224
+ }
225
+ }
226
+ _start(startOpts) {
227
+ if (!this.worker) {
228
+ return Promise.reject("No worker found: perhaps, CSP is not set.");
229
+ }
230
+ if (this.activityState !== ActivityState.NotActive) {
231
+ return Promise.reject("OpenReplay: trying to call `start()` on the instance that has been started already.");
232
+ }
233
+ this.activityState = ActivityState.Starting;
234
+ let pageNo = 0;
235
+ const pageNoStr = sessionStorage.getItem(this.options.session_pageno_key);
236
+ if (pageNoStr != null) {
237
+ pageNo = parseInt(pageNoStr);
238
+ pageNo++;
239
+ }
240
+ sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
241
+ this._userID = startOpts.userID || null;
242
+ this._metadata = startOpts.metadata || {}; // TODO: update both dynamically on corresponding messages
243
+ const startInfo = this.getStartInfo();
244
+ const messageData = {
245
+ ingestPoint: this.options.ingestPoint,
246
+ pageNo,
247
+ startTimestamp: startInfo.timestamp,
248
+ connAttemptCount: this.options.connAttemptCount,
249
+ connAttemptGap: this.options.connAttemptGap,
250
+ };
251
+ this.worker.postMessage(messageData); // brings delay of 10th ms?
252
+ const sReset = sessionStorage.getItem(this.options.session_reset_key);
253
+ sessionStorage.removeItem(this.options.session_reset_key);
254
+ return window.fetch(this.options.ingestPoint + '/v1/web/start', {
255
+ method: 'POST',
256
+ headers: {
257
+ 'Content-Type': 'application/json',
258
+ },
259
+ body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { token: sessionStorage.getItem(this.options.session_token_key), deviceMemory,
260
+ jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
261
+ })
262
+ .then(r => {
263
+ if (r.status === 200) {
264
+ return r.json();
265
+ }
266
+ else {
267
+ return r.text().then(text => text === CANCELED
268
+ ? Promise.reject(CANCELED)
269
+ : Promise.reject(`Server error: ${r.status}. ${text}`));
270
+ }
271
+ })
272
+ .then(r => {
183
273
  if (!this.worker) {
184
- return Promise.reject("No worker found: perhaps, CSP is not set.");
274
+ return Promise.reject("no worker found after start request (this might not happen)");
185
275
  }
186
- this.isActive = true;
187
- let pageNo = 0;
188
- const pageNoStr = sessionStorage.getItem(this.options.session_pageno_key);
189
- if (pageNoStr != null) {
190
- pageNo = parseInt(pageNoStr);
191
- pageNo++;
276
+ const { token, userUUID, sessionID, beaconSizeLimit } = r;
277
+ if (typeof token !== 'string' ||
278
+ typeof userUUID !== 'string' ||
279
+ (typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) {
280
+ return Promise.reject(`Incorrect server response: ${JSON.stringify(r)}`);
192
281
  }
193
- sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
194
- const startTimestamp = timestamp();
195
- const messageData = {
196
- ingestPoint: this.options.ingestPoint,
197
- pageNo,
198
- startTimestamp,
199
- connAttemptCount: this.options.connAttemptCount,
200
- connAttemptGap: this.options.connAttemptGap,
201
- };
202
- this.worker.postMessage(messageData); // brings delay of 10th ms?
203
- // let token = sessionStorage.getItem(this.options.session_token_key)
204
- // const tokenIsActive = localStorage.getItem("__or_at_" + token)
205
- // if (tokenIsActive) {
206
- // token = null
207
- // }
208
- return window.fetch(this.options.ingestPoint + '/v1/web/start', {
209
- method: 'POST',
210
- headers: {
211
- 'Content-Type': 'application/json',
212
- },
213
- body: JSON.stringify({
214
- token: sessionStorage.getItem(this.options.session_token_key),
215
- userUUID: localStorage.getItem(this.options.local_uuid_key),
216
- projectKey: this.projectKey,
217
- revID: this.revID,
218
- timestamp: startTimestamp,
219
- trackerVersion: this.version,
220
- isSnippet: this.options.__is_snippet,
221
- deviceMemory,
222
- jsHeapSizeLimit,
223
- reset,
224
- }),
225
- })
226
- .then(r => {
227
- if (r.status === 200) {
228
- return r.json();
229
- }
230
- else { // TODO: handle canceling && 403
231
- return r.text().then(text => {
232
- throw new Error(`Server error: ${r.status}. ${text}`);
233
- });
234
- }
235
- })
236
- .then(r => {
237
- const { token, userUUID, sessionID, beaconSizeLimit } = r;
238
- if (typeof token !== 'string' ||
239
- typeof userUUID !== 'string' ||
240
- (typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) {
241
- throw new Error(`Incorrect server response: ${JSON.stringify(r)}`);
242
- }
243
- sessionStorage.setItem(this.options.session_token_key, token);
244
- localStorage.setItem(this.options.local_uuid_key, userUUID);
245
- // localStorage.setItem("__or_at_" + token, "true")
246
- // this.attachEventListener(window, 'beforeunload', ()=>{
247
- // localStorage.removeItem("__or_at_" + token)
248
- // }, false);
249
- // this.attachEventListener(window, 'pagehide', ()=>{
250
- // localStorage.removeItem("__or_at_" + token)
251
- // }, false);
252
- if (typeof sessionID === 'string') {
253
- this._sessionID = sessionID;
254
- }
255
- if (!this.worker) {
256
- throw new Error("no worker found after start request (this might not happen)");
257
- }
258
- this.worker.postMessage({ token, beaconSizeLimit });
259
- this.startCallbacks.forEach((cb) => cb());
260
- this.observer.observe();
261
- this.ticker.start();
262
- log("OpenReplay tracking started.");
263
- const onStartInfo = { sessionToken: token, userUUID, sessionID };
264
- if (typeof this.options.onStart === 'function') {
265
- this.options.onStart(onStartInfo);
266
- }
267
- return onStartInfo;
268
- })
269
- .catch(e => {
270
- sessionStorage.removeItem(this.options.session_token_key);
271
- this.stop();
272
- warn("OpenReplay was unable to start. ", e);
273
- this._debug("session_start", e);
274
- throw e;
275
- });
276
- }
277
- return Promise.reject("Player is already active");
282
+ sessionStorage.setItem(this.options.session_token_key, token);
283
+ localStorage.setItem(this.options.local_uuid_key, userUUID);
284
+ if (typeof sessionID === 'string') {
285
+ this._sessionID = sessionID;
286
+ }
287
+ this.activityState = ActivityState.Active;
288
+ this.worker.postMessage({ token, beaconSizeLimit });
289
+ this.startCallbacks.forEach((cb) => cb());
290
+ this.observer.observe();
291
+ this.ticker.start();
292
+ Object.entries(this._metadata).forEach(([key, value]) => this.send(new Metadata(key, value)));
293
+ this.notify.log("OpenReplay tracking started.");
294
+ // TODO: get rid of onStart
295
+ const onStartInfo = { sessionToken: token, userUUID, sessionID };
296
+ if (typeof this.options.onStart === 'function') {
297
+ this.options.onStart(onStartInfo);
298
+ }
299
+ return onStartInfo;
300
+ })
301
+ .catch(reason => {
302
+ sessionStorage.removeItem(this.options.session_token_key);
303
+ this.stop();
304
+ //if (reason === CANCELED) { return Promise.resolve(CANCELED) } // TODO: what to return ????? Throwing is baad
305
+ if (reason !== CANCELED) {
306
+ this.notify.log("OpenReplay was unable to start. ", reason);
307
+ this._debug("session_start", reason);
308
+ }
309
+ return Promise.reject(reason);
310
+ });
278
311
  }
279
- start(reset = false) {
312
+ start(options = { forceNew: false }) {
280
313
  if (!document.hidden) {
281
- return this._start(reset);
314
+ return this._start(options);
282
315
  }
283
316
  else {
284
317
  return new Promise((resolve) => {
285
318
  const onVisibilityChange = () => {
286
319
  if (!document.hidden) {
287
320
  document.removeEventListener("visibilitychange", onVisibilityChange);
288
- resolve(this._start(reset));
321
+ resolve(this._start(options));
289
322
  }
290
323
  };
291
324
  document.addEventListener("visibilitychange", onVisibilityChange);
@@ -293,19 +326,20 @@ export default class App {
293
326
  }
294
327
  }
295
328
  stop() {
296
- if (this.isActive) {
329
+ if (this.activityState !== ActivityState.NotActive) {
297
330
  try {
298
331
  if (this.worker) {
299
332
  this.worker.postMessage("stop");
300
333
  }
334
+ this.sanitizer.clear();
301
335
  this.observer.disconnect();
302
336
  this.nodes.clear();
303
337
  this.ticker.stop();
304
338
  this.stopCallbacks.forEach((cb) => cb());
305
- log("OpenReplay tracking stopped.");
339
+ this.notify.log("OpenReplay tracking stopped.");
306
340
  }
307
341
  finally {
308
- this.isActive = false;
342
+ this.activityState = ActivityState.NotActive;
309
343
  }
310
344
  }
311
345
  }
@@ -0,0 +1,27 @@
1
+ export declare const LogLevel: {
2
+ readonly Verbose: 4;
3
+ readonly Errors: 4;
4
+ readonly Warnings: 3;
5
+ readonly Log: 2;
6
+ readonly Silent: 0;
7
+ };
8
+ declare type LogLevel = typeof LogLevel[keyof typeof LogLevel];
9
+ declare type CustomLevel = {
10
+ error: boolean;
11
+ warn: boolean;
12
+ log: boolean;
13
+ };
14
+ interface _Options {
15
+ level: LogLevel | CustomLevel;
16
+ messages?: number[];
17
+ }
18
+ export declare type Options = true | _Options | LogLevel;
19
+ export default class Logger {
20
+ private readonly options;
21
+ private readonly opts;
22
+ constructor(options?: Options);
23
+ log(...args: any): void;
24
+ warn(...args: any): void;
25
+ error(...args: any): void;
26
+ }
27
+ export {};
package/lib/app/logger.js CHANGED
@@ -1 +1,39 @@
1
- "use strict";
1
+ export const LogLevel = {
2
+ Verbose: 4,
3
+ Errors: 4,
4
+ Warnings: 3,
5
+ Log: 2,
6
+ Silent: 0,
7
+ };
8
+ function IsCustomLevel(l) {
9
+ return typeof l === 'object';
10
+ }
11
+ export default class Logger {
12
+ constructor(options = LogLevel.Silent) {
13
+ this.options = options;
14
+ this.opts = options === true
15
+ ? { level: LogLevel.Verbose }
16
+ : typeof options === "number" ? { level: options } : options;
17
+ }
18
+ log(...args) {
19
+ if (IsCustomLevel(this.opts.level)
20
+ ? this.opts.level.log
21
+ : this.opts.level >= LogLevel.Log) {
22
+ console.log(...args);
23
+ }
24
+ }
25
+ warn(...args) {
26
+ if (IsCustomLevel(this.opts.level)
27
+ ? this.opts.level.warn
28
+ : this.opts.level >= LogLevel.Warnings) {
29
+ console.warn(...args);
30
+ }
31
+ }
32
+ error(...args) {
33
+ if (IsCustomLevel(this.opts.level)
34
+ ? this.opts.level.error
35
+ : this.opts.level >= LogLevel.Errors) {
36
+ console.error(...args);
37
+ }
38
+ }
39
+ }
@@ -1,25 +1,5 @@
1
1
  import App from "../index.js";
2
- export interface Window extends globalThis.Window {
3
- HTMLInputElement: typeof HTMLInputElement;
4
- HTMLLinkElement: typeof HTMLLinkElement;
5
- HTMLStyleElement: typeof HTMLStyleElement;
6
- SVGStyleElement: typeof SVGStyleElement;
7
- HTMLIFrameElement: typeof HTMLIFrameElement;
8
- Text: typeof Text;
9
- Element: typeof Element;
10
- ShadowRoot: typeof ShadowRoot;
11
- }
12
- declare type WindowConstructor = Document | Element | Text | ShadowRoot | HTMLInputElement | HTMLLinkElement | HTMLStyleElement | HTMLIFrameElement;
13
- declare type Constructor<T> = {
14
- new (...args: any[]): T;
15
- name: string;
16
- };
17
- export declare function isInstance<T extends WindowConstructor>(node: Node, constr: Constructor<T>): node is T;
18
- export interface Options {
19
- obscureTextEmails: boolean;
20
- obscureTextNumbers: boolean;
21
- }
22
- export default abstract class Observer<AdditionalOptions = {}> {
2
+ export default abstract class Observer {
23
3
  protected readonly app: App;
24
4
  protected readonly context: Window;
25
5
  private readonly observer;
@@ -29,14 +9,10 @@ export default abstract class Observer<AdditionalOptions = {}> {
29
9
  private readonly indexes;
30
10
  private readonly attributesList;
31
11
  private readonly textSet;
32
- private readonly textMasked;
33
- protected readonly options: Options & AdditionalOptions;
34
12
  private readonly inUpperContext;
35
- constructor(app: App, options: Partial<Options> & AdditionalOptions, context?: Window);
13
+ constructor(app: App, context?: Window);
36
14
  private clear;
37
15
  private sendNodeAttribute;
38
- getInnerTextSecure(el: HTMLElement): string;
39
- private checkObscure;
40
16
  private sendNodeData;
41
17
  private bindNode;
42
18
  private bindTree;
@@ -47,4 +23,3 @@ export default abstract class Observer<AdditionalOptions = {}> {
47
23
  protected observeRoot(node: Node, beforeCommit: (id?: number) => unknown, nodeToBind?: Node): void;
48
24
  disconnect(): void;
49
25
  }
50
- export {};