@openreplay/tracker 3.4.17-beta.1 → 3.5.2
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.
- package/README.md +8 -1
- package/cjs/app/index.d.ts +30 -4
- package/cjs/app/index.js +148 -117
- package/cjs/app/logger.d.ts +27 -0
- package/cjs/app/logger.js +42 -0
- package/cjs/index.d.ts +10 -10
- package/cjs/index.js +32 -27
- package/cjs/modules/console.js +1 -1
- package/cjs/modules/mouse.js +2 -0
- package/cjs/utils.d.ts +0 -8
- package/cjs/utils.js +3 -4
- package/lib/app/index.d.ts +30 -4
- package/lib/app/index.js +149 -118
- package/lib/app/logger.d.ts +27 -0
- package/lib/app/logger.js +39 -1
- package/lib/index.d.ts +10 -10
- package/lib/index.js +32 -27
- package/lib/modules/console.js +1 -1
- package/lib/modules/mouse.js +2 -0
- package/lib/utils.d.ts +0 -8
- package/lib/utils.js +2 -3
- package/package.json +1 -1
package/lib/app/index.js
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
|
-
import { timestamp
|
|
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
5
|
import Sanitizer from "./sanitizer.js";
|
|
6
6
|
import Ticker from "./ticker.js";
|
|
7
|
+
import Logger, { LogLevel } from "./logger.js";
|
|
7
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";
|
|
8
16
|
// TODO: use backendHost only
|
|
9
17
|
export const DEFAULT_INGEST_POINT = 'https://api.openreplay.com/ingest';
|
|
10
18
|
export default class App {
|
|
11
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
|
|
12
23
|
this.messages = [];
|
|
13
24
|
this.startCallbacks = [];
|
|
14
25
|
this.stopCallbacks = [];
|
|
15
26
|
this.commitCallbacks = [];
|
|
16
27
|
this._sessionID = null;
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
28
|
+
this._userID = null;
|
|
29
|
+
this._metadata = {};
|
|
30
|
+
this.activityState = ActivityState.NotActive;
|
|
31
|
+
this.version = '3.5.2'; // TODO: version compatability check inside each plugin.
|
|
32
|
+
this.preStartMessages = [];
|
|
19
33
|
this.projectKey = projectKey;
|
|
20
34
|
this.options = Object.assign({
|
|
21
35
|
revID: '',
|
|
@@ -26,9 +40,9 @@ export default class App {
|
|
|
26
40
|
local_uuid_key: '__openreplay_uuid',
|
|
27
41
|
ingestPoint: DEFAULT_INGEST_POINT,
|
|
28
42
|
resourceBaseHref: null,
|
|
43
|
+
verbose: false,
|
|
29
44
|
__is_snippet: false,
|
|
30
45
|
__debug_report_edp: null,
|
|
31
|
-
__debug_log: false,
|
|
32
46
|
}, options);
|
|
33
47
|
if (sessionToken != null) {
|
|
34
48
|
sessionStorage.setItem(this.options.session_token_key, sessionToken);
|
|
@@ -39,8 +53,10 @@ export default class App {
|
|
|
39
53
|
this.observer = new Observer(this, options);
|
|
40
54
|
this.ticker = new Ticker(this);
|
|
41
55
|
this.ticker.attach(() => this.commit());
|
|
56
|
+
this.debug = new Logger(this.options.__debug__);
|
|
57
|
+
this.notify = new Logger(this.options.verbose ? LogLevel.Warnings : LogLevel.Silent);
|
|
42
58
|
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()};
|
|
59
|
+
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
60
|
`], { type: 'text/javascript' })));
|
|
45
61
|
this.worker.onerror = e => {
|
|
46
62
|
this._debug("webworker_error", e);
|
|
@@ -53,7 +69,11 @@ export default class App {
|
|
|
53
69
|
}
|
|
54
70
|
else if (data === "restart") {
|
|
55
71
|
this.stop();
|
|
56
|
-
this.start(
|
|
72
|
+
this.start({
|
|
73
|
+
forceNew: true,
|
|
74
|
+
userID: this._userID || undefined,
|
|
75
|
+
metadata: this._metadata || undefined,
|
|
76
|
+
});
|
|
57
77
|
}
|
|
58
78
|
};
|
|
59
79
|
const alertWorker = () => {
|
|
@@ -81,14 +101,19 @@ export default class App {
|
|
|
81
101
|
})
|
|
82
102
|
});
|
|
83
103
|
}
|
|
84
|
-
|
|
85
|
-
warn("OpenReplay error: ", context, e);
|
|
86
|
-
}
|
|
104
|
+
this.debug.error("OpenReplay error: ", context, e);
|
|
87
105
|
}
|
|
88
106
|
send(message, urgent = false) {
|
|
89
|
-
if (
|
|
107
|
+
if (this.activityState === ActivityState.NotActive) {
|
|
90
108
|
return;
|
|
91
109
|
}
|
|
110
|
+
if (this.activityState === ActivityState.Starting) {
|
|
111
|
+
this.preStartMessages.push(message);
|
|
112
|
+
}
|
|
113
|
+
if (this.preStartMessages.length) {
|
|
114
|
+
this.messages.push(...this.preStartMessages);
|
|
115
|
+
this.preStartMessages.length = 0;
|
|
116
|
+
}
|
|
92
117
|
this.messages.push(message);
|
|
93
118
|
if (urgent) {
|
|
94
119
|
this.commit();
|
|
@@ -105,10 +130,6 @@ export default class App {
|
|
|
105
130
|
attachCommitCallback(cb) {
|
|
106
131
|
this.commitCallbacks.push(cb);
|
|
107
132
|
}
|
|
108
|
-
// @Depricated (TODO: remove in 3.5.*)
|
|
109
|
-
addCommitCallback(cb) {
|
|
110
|
-
this.attachCommitCallback(cb);
|
|
111
|
-
}
|
|
112
133
|
safe(fn) {
|
|
113
134
|
const app = this;
|
|
114
135
|
return function (...args) {
|
|
@@ -137,6 +158,30 @@ export default class App {
|
|
|
137
158
|
this.attachStartCallback(() => target.addEventListener(type, listener, useCapture));
|
|
138
159
|
this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture));
|
|
139
160
|
}
|
|
161
|
+
checkRequiredVersion(version) {
|
|
162
|
+
const reqVer = version.split('.');
|
|
163
|
+
const ver = this.version.split('.');
|
|
164
|
+
for (let i = 0; i < ver.length; i++) {
|
|
165
|
+
if (Number(ver[i]) < Number(reqVer[i]) || isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
getStartInfo() {
|
|
172
|
+
return {
|
|
173
|
+
userUUID: localStorage.getItem(this.options.local_uuid_key),
|
|
174
|
+
projectKey: this.projectKey,
|
|
175
|
+
revID: this.revID,
|
|
176
|
+
timestamp: timestamp(),
|
|
177
|
+
trackerVersion: this.version,
|
|
178
|
+
userID: this._userID,
|
|
179
|
+
isSnippet: this.options.__is_snippet,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
getSessionInfo() {
|
|
183
|
+
return Object.assign({ sessionID: this._sessionID, metadata: this._metadata }, this.getStartInfo());
|
|
184
|
+
}
|
|
140
185
|
getSessionToken() {
|
|
141
186
|
const token = sessionStorage.getItem(this.options.session_token_key);
|
|
142
187
|
if (token !== null) {
|
|
@@ -176,7 +221,7 @@ export default class App {
|
|
|
176
221
|
return url.startsWith(this.options.ingestPoint);
|
|
177
222
|
}
|
|
178
223
|
active() {
|
|
179
|
-
return this.
|
|
224
|
+
return this.activityState === ActivityState.Active;
|
|
180
225
|
}
|
|
181
226
|
resetNextPageSession(flag) {
|
|
182
227
|
if (flag) {
|
|
@@ -186,116 +231,102 @@ export default class App {
|
|
|
186
231
|
sessionStorage.removeItem(this.options.session_reset_key);
|
|
187
232
|
}
|
|
188
233
|
}
|
|
189
|
-
_start(
|
|
190
|
-
if (!this.
|
|
234
|
+
_start(startOpts) {
|
|
235
|
+
if (!this.worker) {
|
|
236
|
+
return Promise.reject("No worker found: perhaps, CSP is not set.");
|
|
237
|
+
}
|
|
238
|
+
if (this.activityState !== ActivityState.NotActive) {
|
|
239
|
+
return Promise.reject("OpenReplay: trying to call `start()` on the instance that has been started already.");
|
|
240
|
+
}
|
|
241
|
+
this.activityState = ActivityState.Starting;
|
|
242
|
+
let pageNo = 0;
|
|
243
|
+
const pageNoStr = sessionStorage.getItem(this.options.session_pageno_key);
|
|
244
|
+
if (pageNoStr != null) {
|
|
245
|
+
pageNo = parseInt(pageNoStr);
|
|
246
|
+
pageNo++;
|
|
247
|
+
}
|
|
248
|
+
sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
|
|
249
|
+
this._userID = startOpts.userID || null;
|
|
250
|
+
this._metadata = startOpts.metadata || {}; // TODO: update both dynamically on corresponding messages
|
|
251
|
+
const startInfo = this.getStartInfo();
|
|
252
|
+
const messageData = {
|
|
253
|
+
ingestPoint: this.options.ingestPoint,
|
|
254
|
+
pageNo,
|
|
255
|
+
startTimestamp: startInfo.timestamp,
|
|
256
|
+
connAttemptCount: this.options.connAttemptCount,
|
|
257
|
+
connAttemptGap: this.options.connAttemptGap,
|
|
258
|
+
};
|
|
259
|
+
this.worker.postMessage(messageData); // brings delay of 10th ms?
|
|
260
|
+
const sReset = sessionStorage.getItem(this.options.session_reset_key);
|
|
261
|
+
sessionStorage.removeItem(this.options.session_reset_key);
|
|
262
|
+
return window.fetch(this.options.ingestPoint + '/v1/web/start', {
|
|
263
|
+
method: 'POST',
|
|
264
|
+
headers: {
|
|
265
|
+
'Content-Type': 'application/json',
|
|
266
|
+
},
|
|
267
|
+
body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { token: sessionStorage.getItem(this.options.session_token_key), deviceMemory,
|
|
268
|
+
jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
|
|
269
|
+
})
|
|
270
|
+
.then(r => {
|
|
271
|
+
if (r.status === 200) {
|
|
272
|
+
return r.json();
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
return r.text().then(text => text === CANCELED
|
|
276
|
+
? Promise.reject(CANCELED) // TODO: return {error: CANCELED} instead
|
|
277
|
+
: Promise.reject(`Server error: ${r.status}. ${text}`));
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
.then(r => {
|
|
191
281
|
if (!this.worker) {
|
|
192
|
-
return Promise.reject("
|
|
282
|
+
return Promise.reject("no worker found after start request (this might not happen)");
|
|
193
283
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
pageNo++;
|
|
284
|
+
const { token, userUUID, sessionID, beaconSizeLimit } = r;
|
|
285
|
+
if (typeof token !== 'string' ||
|
|
286
|
+
typeof userUUID !== 'string' ||
|
|
287
|
+
(typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) {
|
|
288
|
+
return Promise.reject(`Incorrect server response: ${JSON.stringify(r)}`);
|
|
200
289
|
}
|
|
201
|
-
sessionStorage.setItem(this.options.
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
this.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
isSnippet: this.options.__is_snippet,
|
|
231
|
-
deviceMemory,
|
|
232
|
-
jsHeapSizeLimit,
|
|
233
|
-
reset: reset || sReset !== null,
|
|
234
|
-
}),
|
|
235
|
-
})
|
|
236
|
-
.then(r => {
|
|
237
|
-
if (r.status === 200) {
|
|
238
|
-
return r.json();
|
|
239
|
-
}
|
|
240
|
-
else { // TODO: handle canceling && 403
|
|
241
|
-
return r.text().then(text => {
|
|
242
|
-
throw new Error(`Server error: ${r.status}. ${text}`);
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
})
|
|
246
|
-
.then(r => {
|
|
247
|
-
const { token, userUUID, sessionID, beaconSizeLimit } = r;
|
|
248
|
-
if (typeof token !== 'string' ||
|
|
249
|
-
typeof userUUID !== 'string' ||
|
|
250
|
-
(typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) {
|
|
251
|
-
throw new Error(`Incorrect server response: ${JSON.stringify(r)}`);
|
|
252
|
-
}
|
|
253
|
-
sessionStorage.setItem(this.options.session_token_key, token);
|
|
254
|
-
localStorage.setItem(this.options.local_uuid_key, userUUID);
|
|
255
|
-
// localStorage.setItem("__or_at_" + token, "true")
|
|
256
|
-
// this.attachEventListener(window, 'beforeunload', ()=>{
|
|
257
|
-
// localStorage.removeItem("__or_at_" + token)
|
|
258
|
-
// }, false);
|
|
259
|
-
// this.attachEventListener(window, 'pagehide', ()=>{
|
|
260
|
-
// localStorage.removeItem("__or_at_" + token)
|
|
261
|
-
// }, false);
|
|
262
|
-
if (typeof sessionID === 'string') {
|
|
263
|
-
this._sessionID = sessionID;
|
|
264
|
-
}
|
|
265
|
-
if (!this.worker) {
|
|
266
|
-
throw new Error("no worker found after start request (this might not happen)");
|
|
267
|
-
}
|
|
268
|
-
this.worker.postMessage({ token, beaconSizeLimit });
|
|
269
|
-
this.startCallbacks.forEach((cb) => cb());
|
|
270
|
-
this.observer.observe();
|
|
271
|
-
this.ticker.start();
|
|
272
|
-
log("OpenReplay tracking started.");
|
|
273
|
-
const onStartInfo = { sessionToken: token, userUUID, sessionID };
|
|
274
|
-
if (typeof this.options.onStart === 'function') {
|
|
275
|
-
this.options.onStart(onStartInfo);
|
|
276
|
-
}
|
|
277
|
-
return onStartInfo;
|
|
278
|
-
})
|
|
279
|
-
.catch(e => {
|
|
280
|
-
sessionStorage.removeItem(this.options.session_token_key);
|
|
281
|
-
this.stop();
|
|
282
|
-
warn("OpenReplay was unable to start. ", e);
|
|
283
|
-
this._debug("session_start", e);
|
|
284
|
-
throw e;
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
return Promise.reject("Player is already active");
|
|
290
|
+
sessionStorage.setItem(this.options.session_token_key, token);
|
|
291
|
+
localStorage.setItem(this.options.local_uuid_key, userUUID);
|
|
292
|
+
if (typeof sessionID === 'string') {
|
|
293
|
+
this._sessionID = sessionID;
|
|
294
|
+
}
|
|
295
|
+
this.activityState = ActivityState.Active;
|
|
296
|
+
this.worker.postMessage({ token, beaconSizeLimit });
|
|
297
|
+
this.startCallbacks.forEach((cb) => cb());
|
|
298
|
+
this.observer.observe();
|
|
299
|
+
this.ticker.start();
|
|
300
|
+
Object.entries(this._metadata).forEach(([key, value]) => this.send(new Metadata(key, value)));
|
|
301
|
+
this.notify.log("OpenReplay tracking started.");
|
|
302
|
+
// TODO: get rid of onStart
|
|
303
|
+
const onStartInfo = { sessionToken: token, userUUID, sessionID };
|
|
304
|
+
if (typeof this.options.onStart === 'function') {
|
|
305
|
+
this.options.onStart(onStartInfo);
|
|
306
|
+
}
|
|
307
|
+
return onStartInfo;
|
|
308
|
+
})
|
|
309
|
+
.catch(reason => {
|
|
310
|
+
sessionStorage.removeItem(this.options.session_token_key);
|
|
311
|
+
this.stop();
|
|
312
|
+
//if (reason === CANCELED) { return Promise.resolve(CANCELED) } // TODO: what to return ????? Throwing is baad
|
|
313
|
+
if (reason !== CANCELED) {
|
|
314
|
+
this.notify.log("OpenReplay was unable to start. ", reason);
|
|
315
|
+
this._debug("session_start", reason);
|
|
316
|
+
}
|
|
317
|
+
return Promise.reject(reason);
|
|
318
|
+
});
|
|
288
319
|
}
|
|
289
|
-
start(
|
|
320
|
+
start(options = { forceNew: false }) {
|
|
290
321
|
if (!document.hidden) {
|
|
291
|
-
return this._start(
|
|
322
|
+
return this._start(options);
|
|
292
323
|
}
|
|
293
324
|
else {
|
|
294
325
|
return new Promise((resolve) => {
|
|
295
326
|
const onVisibilityChange = () => {
|
|
296
327
|
if (!document.hidden) {
|
|
297
328
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
298
|
-
resolve(this._start(
|
|
329
|
+
resolve(this._start(options));
|
|
299
330
|
}
|
|
300
331
|
};
|
|
301
332
|
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
@@ -303,7 +334,7 @@ export default class App {
|
|
|
303
334
|
}
|
|
304
335
|
}
|
|
305
336
|
stop() {
|
|
306
|
-
if (this.
|
|
337
|
+
if (this.activityState !== ActivityState.NotActive) {
|
|
307
338
|
try {
|
|
308
339
|
if (this.worker) {
|
|
309
340
|
this.worker.postMessage("stop");
|
|
@@ -313,10 +344,10 @@ export default class App {
|
|
|
313
344
|
this.nodes.clear();
|
|
314
345
|
this.ticker.stop();
|
|
315
346
|
this.stopCallbacks.forEach((cb) => cb());
|
|
316
|
-
log("OpenReplay tracking stopped.");
|
|
347
|
+
this.notify.log("OpenReplay tracking stopped.");
|
|
317
348
|
}
|
|
318
349
|
finally {
|
|
319
|
-
this.
|
|
350
|
+
this.activityState = ActivityState.NotActive;
|
|
320
351
|
}
|
|
321
352
|
}
|
|
322
353
|
}
|
package/lib/app/logger.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -2,18 +2,20 @@ import App from "./app/index.js";
|
|
|
2
2
|
export { default as App } from './app/index.js';
|
|
3
3
|
import * as _Messages from "./messages/index.js";
|
|
4
4
|
export declare const Messages: typeof _Messages;
|
|
5
|
-
import { Options as AppOptions } from "./app/index.js";
|
|
6
|
-
import { Options as ConsoleOptions } from "./modules/console.js";
|
|
7
|
-
import { Options as ExceptionOptions } from "./modules/exception.js";
|
|
8
|
-
import { Options as InputOptions } from "./modules/input.js";
|
|
9
|
-
import { Options as PerformanceOptions } from "./modules/performance.js";
|
|
10
|
-
import { Options as TimingOptions } from "./modules/timing.js";
|
|
11
|
-
|
|
5
|
+
import type { Options as AppOptions } from "./app/index.js";
|
|
6
|
+
import type { Options as ConsoleOptions } from "./modules/console.js";
|
|
7
|
+
import type { Options as ExceptionOptions } from "./modules/exception.js";
|
|
8
|
+
import type { Options as InputOptions } from "./modules/input.js";
|
|
9
|
+
import type { Options as PerformanceOptions } from "./modules/performance.js";
|
|
10
|
+
import type { Options as TimingOptions } from "./modules/timing.js";
|
|
11
|
+
import type { StartOptions } from './app/index.js';
|
|
12
|
+
import type { OnStartInfo } from './app/index.js';
|
|
12
13
|
export declare type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & InputOptions & PerformanceOptions & TimingOptions> & {
|
|
13
14
|
projectID?: number;
|
|
14
15
|
projectKey: string;
|
|
15
16
|
sessionToken?: string;
|
|
16
17
|
respectDoNotTrack?: boolean;
|
|
18
|
+
autoResetOnWindowOpen?: boolean;
|
|
17
19
|
__DISABLE_SECURE_MODE?: boolean;
|
|
18
20
|
};
|
|
19
21
|
export default class API {
|
|
@@ -22,8 +24,7 @@ export default class API {
|
|
|
22
24
|
constructor(options: Options);
|
|
23
25
|
use<T>(fn: (app: App | null, options?: Options) => T): T;
|
|
24
26
|
isActive(): boolean;
|
|
25
|
-
|
|
26
|
-
start(): Promise<import("./app/index.js").OnStartInfo>;
|
|
27
|
+
start(startOpts?: StartOptions): Promise<OnStartInfo>;
|
|
27
28
|
stop(): void;
|
|
28
29
|
getSessionToken(): string | null | undefined;
|
|
29
30
|
getSessionID(): string | null | undefined;
|
|
@@ -37,5 +38,4 @@ export default class API {
|
|
|
37
38
|
event(key: string, payload: any, issue?: boolean): void;
|
|
38
39
|
issue(key: string, payload: any): void;
|
|
39
40
|
handleError: (e: Error | ErrorEvent | PromiseRejectionEvent) => void;
|
|
40
|
-
resetNextPageSession(flag: boolean): void;
|
|
41
41
|
}
|
package/lib/index.js
CHANGED
|
@@ -77,7 +77,7 @@ export default class API {
|
|
|
77
77
|
(navigator.doNotTrack == '1'
|
|
78
78
|
// @ts-ignore
|
|
79
79
|
|| window.doNotTrack == '1');
|
|
80
|
-
this.app = doNotTrack ||
|
|
80
|
+
const app = this.app = doNotTrack ||
|
|
81
81
|
!('Map' in window) ||
|
|
82
82
|
!('Set' in window) ||
|
|
83
83
|
!('MutationObserver' in window) ||
|
|
@@ -88,20 +88,34 @@ export default class API {
|
|
|
88
88
|
!('Worker' in window)
|
|
89
89
|
? null
|
|
90
90
|
: new App(options.projectKey, options.sessionToken, options);
|
|
91
|
-
if (
|
|
92
|
-
Viewport(
|
|
93
|
-
CSSRules(
|
|
94
|
-
Connection(
|
|
95
|
-
Console(
|
|
96
|
-
Exception(
|
|
97
|
-
Img(
|
|
98
|
-
Input(
|
|
99
|
-
Mouse(
|
|
100
|
-
Timing(
|
|
101
|
-
Performance(
|
|
102
|
-
Scroll(
|
|
103
|
-
Longtasks(
|
|
91
|
+
if (app !== null) {
|
|
92
|
+
Viewport(app);
|
|
93
|
+
CSSRules(app);
|
|
94
|
+
Connection(app);
|
|
95
|
+
Console(app, options);
|
|
96
|
+
Exception(app, options);
|
|
97
|
+
Img(app);
|
|
98
|
+
Input(app, options);
|
|
99
|
+
Mouse(app);
|
|
100
|
+
Timing(app, options);
|
|
101
|
+
Performance(app, options);
|
|
102
|
+
Scroll(app);
|
|
103
|
+
Longtasks(app);
|
|
104
104
|
window.__OPENREPLAY__ = this;
|
|
105
|
+
if (options.autoResetOnWindowOpen) {
|
|
106
|
+
const wOpen = window.open;
|
|
107
|
+
app.attachStartCallback(() => {
|
|
108
|
+
// @ts-ignore ?
|
|
109
|
+
window.open = function (...args) {
|
|
110
|
+
app.resetNextPageSession(true);
|
|
111
|
+
wOpen.call(window, ...args);
|
|
112
|
+
app.resetNextPageSession(false);
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
app.attachStopCallback(() => {
|
|
116
|
+
window.open = wOpen;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
105
119
|
}
|
|
106
120
|
else {
|
|
107
121
|
console.log("OpenReplay: browser doesn't support API required for tracking or doNotTrack is set to 1.");
|
|
@@ -111,7 +125,7 @@ export default class API {
|
|
|
111
125
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
112
126
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
113
127
|
req.send(JSON.stringify({
|
|
114
|
-
trackerVersion: '3.
|
|
128
|
+
trackerVersion: '3.5.2',
|
|
115
129
|
projectKey: options.projectKey,
|
|
116
130
|
doNotTrack,
|
|
117
131
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -127,11 +141,7 @@ export default class API {
|
|
|
127
141
|
}
|
|
128
142
|
return this.app.active();
|
|
129
143
|
}
|
|
130
|
-
|
|
131
|
-
deprecationWarn("'active' method", "'isActive' method", "/");
|
|
132
|
-
return this.isActive();
|
|
133
|
-
}
|
|
134
|
-
start() {
|
|
144
|
+
start(startOpts) {
|
|
135
145
|
if (!IN_BROWSER) {
|
|
136
146
|
console.error(`OpenReplay: you are trying to start Tracker on a node.js environment. If you want to use OpenReplay with SSR, please, use componentDidMount or useEffect API for placing the \`tracker.start()\` line. Check documentation on ${DOCS_HOST}${DOCS_SETUP}`);
|
|
137
147
|
return Promise.reject("Trying to start not in browser.");
|
|
@@ -139,7 +149,8 @@ export default class API {
|
|
|
139
149
|
if (this.app === null) {
|
|
140
150
|
return Promise.reject("Browser doesn't support required api, or doNotTrack is active.");
|
|
141
151
|
}
|
|
142
|
-
|
|
152
|
+
// TODO: check argument typing
|
|
153
|
+
return this.app.start(startOpts);
|
|
143
154
|
}
|
|
144
155
|
stop() {
|
|
145
156
|
if (this.app === null) {
|
|
@@ -219,10 +230,4 @@ export default class API {
|
|
|
219
230
|
this.app.send(new CustomIssue(key, payload));
|
|
220
231
|
}
|
|
221
232
|
}
|
|
222
|
-
resetNextPageSession(flag) {
|
|
223
|
-
if (typeof flag !== 'boolean' || !this.app) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
this.app.resetNextPageSession(flag);
|
|
227
|
-
}
|
|
228
233
|
}
|