@openreplay/tracker 3.5.0 → 3.5.3
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/cjs/app/index.d.ts +5 -5
- package/cjs/app/index.js +21 -26
- package/cjs/app/logger.d.ts +3 -4
- package/cjs/app/logger.js +13 -14
- package/cjs/app/session.d.ts +25 -0
- package/cjs/app/session.js +68 -0
- package/cjs/index.js +3 -5
- package/lib/app/index.d.ts +5 -5
- package/lib/app/index.js +22 -27
- package/lib/app/logger.d.ts +3 -4
- package/lib/app/logger.js +13 -14
- package/lib/app/session.d.ts +25 -0
- package/lib/app/session.js +65 -0
- package/lib/index.js +4 -6
- package/package.json +1 -1
package/cjs/app/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import Nodes from "./nodes.js";
|
|
|
3
3
|
import Sanitizer from "./sanitizer.js";
|
|
4
4
|
import Ticker from "./ticker.js";
|
|
5
5
|
import Logger from "./logger.js";
|
|
6
|
+
import Session from "./session.js";
|
|
6
7
|
import type { Options as ObserverOptions } from "./observer/top_observer.js";
|
|
7
8
|
import type { Options as SanitizerOptions } from "./sanitizer.js";
|
|
8
9
|
import type { Options as LoggerOptions } from "./logger.js";
|
|
@@ -44,6 +45,7 @@ export default class App {
|
|
|
44
45
|
readonly sanitizer: Sanitizer;
|
|
45
46
|
readonly debug: Logger;
|
|
46
47
|
readonly notify: Logger;
|
|
48
|
+
readonly session: Session;
|
|
47
49
|
private readonly messages;
|
|
48
50
|
private readonly observer;
|
|
49
51
|
private readonly startCallbacks;
|
|
@@ -51,18 +53,16 @@ export default class App {
|
|
|
51
53
|
private readonly commitCallbacks;
|
|
52
54
|
private readonly options;
|
|
53
55
|
private readonly revID;
|
|
54
|
-
private _sessionID;
|
|
55
|
-
private _userID;
|
|
56
|
-
private _metadata;
|
|
57
56
|
private activityState;
|
|
58
57
|
private version;
|
|
59
58
|
private readonly worker?;
|
|
60
59
|
constructor(projectKey: string, sessionToken: string | null | undefined, options: Partial<Options>);
|
|
61
60
|
private _debug;
|
|
61
|
+
private readonly preStartMessages;
|
|
62
62
|
send(message: Message, urgent?: boolean): void;
|
|
63
63
|
private commit;
|
|
64
|
-
attachCommitCallback(cb: CommitCallback): void;
|
|
65
64
|
safe<T extends (...args: any[]) => void>(fn: T): T;
|
|
65
|
+
attachCommitCallback(cb: CommitCallback): void;
|
|
66
66
|
attachStartCallback(cb: Callback): void;
|
|
67
67
|
attachStopCallback(cb: Callback): void;
|
|
68
68
|
attachEventListener(target: EventTarget, type: string, listener: EventListener, useSafe?: boolean, useCapture?: boolean): void;
|
|
@@ -74,10 +74,10 @@ export default class App {
|
|
|
74
74
|
revID: string;
|
|
75
75
|
timestamp: number;
|
|
76
76
|
trackerVersion: string;
|
|
77
|
-
userID: string | null;
|
|
78
77
|
isSnippet: boolean;
|
|
79
78
|
sessionID: string | null;
|
|
80
79
|
metadata: Record<string, string>;
|
|
80
|
+
userID: string | null;
|
|
81
81
|
};
|
|
82
82
|
getSessionToken(): string | undefined;
|
|
83
83
|
getSessionID(): string | undefined;
|
package/cjs/app/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const top_observer_js_1 = require("./observer/top_observer.js");
|
|
|
8
8
|
const sanitizer_js_1 = require("./sanitizer.js");
|
|
9
9
|
const ticker_js_1 = require("./ticker.js");
|
|
10
10
|
const logger_js_1 = require("./logger.js");
|
|
11
|
+
const session_js_1 = require("./session.js");
|
|
11
12
|
const performance_js_1 = require("../modules/performance.js");
|
|
12
13
|
var ActivityState;
|
|
13
14
|
(function (ActivityState) {
|
|
@@ -27,11 +28,9 @@ class App {
|
|
|
27
28
|
this.startCallbacks = [];
|
|
28
29
|
this.stopCallbacks = [];
|
|
29
30
|
this.commitCallbacks = [];
|
|
30
|
-
this._sessionID = null;
|
|
31
|
-
this._userID = null;
|
|
32
|
-
this._metadata = {};
|
|
33
31
|
this.activityState = ActivityState.NotActive;
|
|
34
|
-
this.version = '3.5.
|
|
32
|
+
this.version = '3.5.3'; // TODO: version compatability check inside each plugin.
|
|
33
|
+
this.preStartMessages = [];
|
|
35
34
|
this.projectKey = projectKey;
|
|
36
35
|
this.options = Object.assign({
|
|
37
36
|
revID: '',
|
|
@@ -57,25 +56,20 @@ class App {
|
|
|
57
56
|
this.ticker.attach(() => this.commit());
|
|
58
57
|
this.debug = new logger_js_1.default(this.options.__debug__);
|
|
59
58
|
this.notify = new logger_js_1.default(this.options.verbose ? logger_js_1.LogLevel.Warnings : logger_js_1.LogLevel.Silent);
|
|
59
|
+
this.session = new session_js_1.default(this);
|
|
60
60
|
try {
|
|
61
61
|
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()};
|
|
62
62
|
`], { type: 'text/javascript' })));
|
|
63
63
|
this.worker.onerror = e => {
|
|
64
64
|
this._debug("webworker_error", e);
|
|
65
65
|
};
|
|
66
|
-
let lastTs = (0, utils_js_1.timestamp)();
|
|
67
|
-
let fileno = 0;
|
|
68
66
|
this.worker.onmessage = ({ data }) => {
|
|
69
67
|
if (data === null) {
|
|
70
68
|
this.stop();
|
|
71
69
|
}
|
|
72
70
|
else if (data === "restart") {
|
|
73
71
|
this.stop();
|
|
74
|
-
this.start({
|
|
75
|
-
forceNew: true,
|
|
76
|
-
userID: this._userID || undefined,
|
|
77
|
-
metadata: this._metadata || undefined,
|
|
78
|
-
});
|
|
72
|
+
this.start({ forceNew: true });
|
|
79
73
|
}
|
|
80
74
|
};
|
|
81
75
|
const alertWorker = () => {
|
|
@@ -106,9 +100,16 @@ class App {
|
|
|
106
100
|
this.debug.error("OpenReplay error: ", context, e);
|
|
107
101
|
}
|
|
108
102
|
send(message, urgent = false) {
|
|
109
|
-
if (this.activityState
|
|
103
|
+
if (this.activityState === ActivityState.NotActive) {
|
|
110
104
|
return;
|
|
111
105
|
}
|
|
106
|
+
if (this.activityState === ActivityState.Starting) {
|
|
107
|
+
this.preStartMessages.push(message);
|
|
108
|
+
}
|
|
109
|
+
if (this.preStartMessages.length) {
|
|
110
|
+
this.messages.push(...this.preStartMessages);
|
|
111
|
+
this.preStartMessages.length = 0;
|
|
112
|
+
}
|
|
112
113
|
this.messages.push(message);
|
|
113
114
|
if (urgent) {
|
|
114
115
|
this.commit();
|
|
@@ -122,9 +123,6 @@ class App {
|
|
|
122
123
|
this.messages.length = 0;
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
|
-
attachCommitCallback(cb) {
|
|
126
|
-
this.commitCallbacks.push(cb);
|
|
127
|
-
}
|
|
128
126
|
safe(fn) {
|
|
129
127
|
const app = this;
|
|
130
128
|
return function (...args) {
|
|
@@ -140,6 +138,9 @@ class App {
|
|
|
140
138
|
}
|
|
141
139
|
}; // TODO: correct typing
|
|
142
140
|
}
|
|
141
|
+
attachCommitCallback(cb) {
|
|
142
|
+
this.commitCallbacks.push(cb);
|
|
143
|
+
}
|
|
143
144
|
attachStartCallback(cb) {
|
|
144
145
|
this.startCallbacks.push(cb);
|
|
145
146
|
}
|
|
@@ -170,12 +171,11 @@ class App {
|
|
|
170
171
|
revID: this.revID,
|
|
171
172
|
timestamp: (0, utils_js_1.timestamp)(),
|
|
172
173
|
trackerVersion: this.version,
|
|
173
|
-
userID: this._userID,
|
|
174
174
|
isSnippet: this.options.__is_snippet,
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
getSessionInfo() {
|
|
178
|
-
return Object.assign({
|
|
178
|
+
return Object.assign(Object.assign({}, this.session.getInfo()), this.getStartInfo());
|
|
179
179
|
}
|
|
180
180
|
getSessionToken() {
|
|
181
181
|
const token = sessionStorage.getItem(this.options.session_token_key);
|
|
@@ -184,7 +184,7 @@ class App {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
getSessionID() {
|
|
187
|
-
return this.
|
|
187
|
+
return this.session.getInfo().sessionID || undefined;
|
|
188
188
|
}
|
|
189
189
|
getHost() {
|
|
190
190
|
return new URL(this.options.ingestPoint).hostname;
|
|
@@ -241,8 +241,6 @@ class App {
|
|
|
241
241
|
pageNo++;
|
|
242
242
|
}
|
|
243
243
|
sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
|
|
244
|
-
this._userID = startOpts.userID || null;
|
|
245
|
-
this._metadata = startOpts.metadata || {}; // TODO: update both dynamically on corresponding messages
|
|
246
244
|
const startInfo = this.getStartInfo();
|
|
247
245
|
const messageData = {
|
|
248
246
|
ingestPoint: this.options.ingestPoint,
|
|
@@ -259,7 +257,7 @@ class App {
|
|
|
259
257
|
headers: {
|
|
260
258
|
'Content-Type': 'application/json',
|
|
261
259
|
},
|
|
262
|
-
body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { token: sessionStorage.getItem(this.options.session_token_key), deviceMemory: performance_js_1.deviceMemory,
|
|
260
|
+
body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { userID: startOpts.userID || this.session.getInfo().userID, token: sessionStorage.getItem(this.options.session_token_key), deviceMemory: performance_js_1.deviceMemory,
|
|
263
261
|
jsHeapSizeLimit: performance_js_1.jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
|
|
264
262
|
})
|
|
265
263
|
.then(r => {
|
|
@@ -268,7 +266,7 @@ class App {
|
|
|
268
266
|
}
|
|
269
267
|
else {
|
|
270
268
|
return r.text().then(text => text === exports.CANCELED
|
|
271
|
-
? Promise.reject(exports.CANCELED)
|
|
269
|
+
? Promise.reject(exports.CANCELED) // TODO: return {error: CANCELED} instead
|
|
272
270
|
: Promise.reject(`Server error: ${r.status}. ${text}`));
|
|
273
271
|
}
|
|
274
272
|
})
|
|
@@ -284,15 +282,12 @@ class App {
|
|
|
284
282
|
}
|
|
285
283
|
sessionStorage.setItem(this.options.session_token_key, token);
|
|
286
284
|
localStorage.setItem(this.options.local_uuid_key, userUUID);
|
|
287
|
-
|
|
288
|
-
this._sessionID = sessionID;
|
|
289
|
-
}
|
|
285
|
+
this.session.update(Object.assign({ sessionID }, startOpts));
|
|
290
286
|
this.activityState = ActivityState.Active;
|
|
291
287
|
this.worker.postMessage({ token, beaconSizeLimit });
|
|
292
288
|
this.startCallbacks.forEach((cb) => cb());
|
|
293
289
|
this.observer.observe();
|
|
294
290
|
this.ticker.start();
|
|
295
|
-
Object.entries(this._metadata).forEach(([key, value]) => this.send(new index_js_1.Metadata(key, value)));
|
|
296
291
|
this.notify.log("OpenReplay tracking started.");
|
|
297
292
|
// TODO: get rid of onStart
|
|
298
293
|
const onStartInfo = { sessionToken: token, userUUID, sessionID };
|
package/cjs/app/logger.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare const LogLevel: {
|
|
2
|
-
readonly Verbose:
|
|
3
|
-
readonly
|
|
2
|
+
readonly Verbose: 5;
|
|
3
|
+
readonly Log: 4;
|
|
4
4
|
readonly Warnings: 3;
|
|
5
|
-
readonly
|
|
5
|
+
readonly Errors: 2;
|
|
6
6
|
readonly Silent: 0;
|
|
7
7
|
};
|
|
8
8
|
declare type LogLevel = typeof LogLevel[keyof typeof LogLevel];
|
|
@@ -18,7 +18,6 @@ interface _Options {
|
|
|
18
18
|
export declare type Options = true | _Options | LogLevel;
|
|
19
19
|
export default class Logger {
|
|
20
20
|
private readonly options;
|
|
21
|
-
private readonly opts;
|
|
22
21
|
constructor(options?: Options);
|
|
23
22
|
log(...args: any): void;
|
|
24
23
|
warn(...args: any): void;
|
package/cjs/app/logger.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LogLevel = void 0;
|
|
4
4
|
exports.LogLevel = {
|
|
5
|
-
Verbose:
|
|
6
|
-
|
|
5
|
+
Verbose: 5,
|
|
6
|
+
Log: 4,
|
|
7
7
|
Warnings: 3,
|
|
8
|
-
|
|
8
|
+
Errors: 2,
|
|
9
9
|
Silent: 0,
|
|
10
10
|
};
|
|
11
11
|
function IsCustomLevel(l) {
|
|
@@ -13,29 +13,28 @@ function IsCustomLevel(l) {
|
|
|
13
13
|
}
|
|
14
14
|
class Logger {
|
|
15
15
|
constructor(options = exports.LogLevel.Silent) {
|
|
16
|
-
this.options = options
|
|
17
|
-
this.opts = options === true
|
|
16
|
+
this.options = options === true
|
|
18
17
|
? { level: exports.LogLevel.Verbose }
|
|
19
18
|
: typeof options === "number" ? { level: options } : options;
|
|
20
19
|
}
|
|
21
20
|
log(...args) {
|
|
22
|
-
if (IsCustomLevel(this.
|
|
23
|
-
? this.
|
|
24
|
-
: this.
|
|
21
|
+
if (IsCustomLevel(this.options.level)
|
|
22
|
+
? this.options.level.log
|
|
23
|
+
: this.options.level >= exports.LogLevel.Log) {
|
|
25
24
|
console.log(...args);
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
warn(...args) {
|
|
29
|
-
if (IsCustomLevel(this.
|
|
30
|
-
? this.
|
|
31
|
-
: this.
|
|
28
|
+
if (IsCustomLevel(this.options.level)
|
|
29
|
+
? this.options.level.warn
|
|
30
|
+
: this.options.level >= exports.LogLevel.Warnings) {
|
|
32
31
|
console.warn(...args);
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
34
|
error(...args) {
|
|
36
|
-
if (IsCustomLevel(this.
|
|
37
|
-
? this.
|
|
38
|
-
: this.
|
|
35
|
+
if (IsCustomLevel(this.options.level)
|
|
36
|
+
? this.options.level.error
|
|
37
|
+
: this.options.level >= exports.LogLevel.Errors) {
|
|
39
38
|
console.error(...args);
|
|
40
39
|
}
|
|
41
40
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import App from "./index.js";
|
|
2
|
+
interface SessionInfo {
|
|
3
|
+
sessionID: string | null;
|
|
4
|
+
metadata: Record<string, string>;
|
|
5
|
+
userID: string | null;
|
|
6
|
+
}
|
|
7
|
+
declare type OnUpdateCallback = (i: Partial<SessionInfo>) => void;
|
|
8
|
+
export default class Session {
|
|
9
|
+
private app;
|
|
10
|
+
private metadata;
|
|
11
|
+
private userID;
|
|
12
|
+
private sessionID;
|
|
13
|
+
private activityState;
|
|
14
|
+
private callbacks;
|
|
15
|
+
constructor(app: App);
|
|
16
|
+
attachUpdateCallback(cb: OnUpdateCallback): void;
|
|
17
|
+
private handleUpdate;
|
|
18
|
+
update({ userID, metadata, sessionID }: Partial<SessionInfo>): void;
|
|
19
|
+
private _setMetadata;
|
|
20
|
+
private _setUserID;
|
|
21
|
+
setMetadata(key: string, value: string): void;
|
|
22
|
+
setUserID(userID: string): void;
|
|
23
|
+
getInfo(): SessionInfo;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_js_1 = require("../messages/index.js");
|
|
4
|
+
var ActivityState;
|
|
5
|
+
(function (ActivityState) {
|
|
6
|
+
ActivityState[ActivityState["NotActive"] = 0] = "NotActive";
|
|
7
|
+
ActivityState[ActivityState["Starting"] = 1] = "Starting";
|
|
8
|
+
ActivityState[ActivityState["Active"] = 2] = "Active";
|
|
9
|
+
})(ActivityState || (ActivityState = {}));
|
|
10
|
+
class Session {
|
|
11
|
+
constructor(app) {
|
|
12
|
+
this.app = app;
|
|
13
|
+
this.metadata = {};
|
|
14
|
+
this.userID = null;
|
|
15
|
+
this.sessionID = null;
|
|
16
|
+
this.activityState = ActivityState.NotActive;
|
|
17
|
+
this.callbacks = [];
|
|
18
|
+
}
|
|
19
|
+
attachUpdateCallback(cb) {
|
|
20
|
+
this.callbacks.push(cb);
|
|
21
|
+
}
|
|
22
|
+
handleUpdate() {
|
|
23
|
+
const sessInfo = this.getInfo();
|
|
24
|
+
if (sessInfo.userID == null) {
|
|
25
|
+
delete sessInfo.userID;
|
|
26
|
+
}
|
|
27
|
+
if (sessInfo.sessionID == null) {
|
|
28
|
+
delete sessInfo.sessionID;
|
|
29
|
+
}
|
|
30
|
+
this.callbacks.forEach(cb => cb(sessInfo));
|
|
31
|
+
}
|
|
32
|
+
update({ userID, metadata, sessionID }) {
|
|
33
|
+
if (userID != null) { // TODO clear nullable/undefinable types
|
|
34
|
+
this._setUserID(userID);
|
|
35
|
+
}
|
|
36
|
+
if (metadata !== undefined) {
|
|
37
|
+
Object.entries(metadata).forEach(kv => this._setMetadata(...kv));
|
|
38
|
+
}
|
|
39
|
+
if (sessionID !== undefined) {
|
|
40
|
+
this.sessionID = sessionID;
|
|
41
|
+
}
|
|
42
|
+
this.handleUpdate();
|
|
43
|
+
}
|
|
44
|
+
_setMetadata(key, value) {
|
|
45
|
+
this.app.send(new index_js_1.Metadata(key, value));
|
|
46
|
+
this.metadata[key] = value;
|
|
47
|
+
}
|
|
48
|
+
_setUserID(userID) {
|
|
49
|
+
this.app.send(new index_js_1.UserID(userID));
|
|
50
|
+
this.userID = userID;
|
|
51
|
+
}
|
|
52
|
+
setMetadata(key, value) {
|
|
53
|
+
this._setMetadata(key, value);
|
|
54
|
+
this.handleUpdate();
|
|
55
|
+
}
|
|
56
|
+
setUserID(userID) {
|
|
57
|
+
this._setUserID(userID);
|
|
58
|
+
this.handleUpdate();
|
|
59
|
+
}
|
|
60
|
+
getInfo() {
|
|
61
|
+
return {
|
|
62
|
+
sessionID: this.sessionID,
|
|
63
|
+
metadata: this.metadata,
|
|
64
|
+
userID: this.userID,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.default = Session;
|
package/cjs/index.js
CHANGED
|
@@ -17,7 +17,6 @@ const timing_js_1 = require("./modules/timing.js");
|
|
|
17
17
|
const performance_js_1 = require("./modules/performance.js");
|
|
18
18
|
const scroll_js_1 = require("./modules/scroll.js");
|
|
19
19
|
const viewport_js_1 = require("./modules/viewport.js");
|
|
20
|
-
const longtasks_js_1 = require("./modules/longtasks.js");
|
|
21
20
|
const cssrules_js_1 = require("./modules/cssrules.js");
|
|
22
21
|
const utils_js_1 = require("./utils.js");
|
|
23
22
|
const DOCS_SETUP = '/installation/setup-or';
|
|
@@ -104,7 +103,6 @@ class API {
|
|
|
104
103
|
(0, timing_js_1.default)(app, options);
|
|
105
104
|
(0, performance_js_1.default)(app, options);
|
|
106
105
|
(0, scroll_js_1.default)(app);
|
|
107
|
-
(0, longtasks_js_1.default)(app);
|
|
108
106
|
window.__OPENREPLAY__ = this;
|
|
109
107
|
if (options.autoResetOnWindowOpen) {
|
|
110
108
|
const wOpen = window.open;
|
|
@@ -129,7 +127,7 @@ class API {
|
|
|
129
127
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
130
128
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
131
129
|
req.send(JSON.stringify({
|
|
132
|
-
trackerVersion: '3.5.
|
|
130
|
+
trackerVersion: '3.5.3',
|
|
133
131
|
projectKey: options.projectKey,
|
|
134
132
|
doNotTrack,
|
|
135
133
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -180,7 +178,7 @@ class API {
|
|
|
180
178
|
}
|
|
181
179
|
setUserID(id) {
|
|
182
180
|
if (typeof id === 'string' && this.app !== null) {
|
|
183
|
-
this.app.
|
|
181
|
+
this.app.session.setUserID(id);
|
|
184
182
|
}
|
|
185
183
|
}
|
|
186
184
|
userID(id) {
|
|
@@ -200,7 +198,7 @@ class API {
|
|
|
200
198
|
if (typeof key === 'string' &&
|
|
201
199
|
typeof value === 'string' &&
|
|
202
200
|
this.app !== null) {
|
|
203
|
-
this.app.
|
|
201
|
+
this.app.session.setMetadata(key, value);
|
|
204
202
|
}
|
|
205
203
|
}
|
|
206
204
|
metadata(key, value) {
|
package/lib/app/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import Nodes from "./nodes.js";
|
|
|
3
3
|
import Sanitizer from "./sanitizer.js";
|
|
4
4
|
import Ticker from "./ticker.js";
|
|
5
5
|
import Logger from "./logger.js";
|
|
6
|
+
import Session from "./session.js";
|
|
6
7
|
import type { Options as ObserverOptions } from "./observer/top_observer.js";
|
|
7
8
|
import type { Options as SanitizerOptions } from "./sanitizer.js";
|
|
8
9
|
import type { Options as LoggerOptions } from "./logger.js";
|
|
@@ -44,6 +45,7 @@ export default class App {
|
|
|
44
45
|
readonly sanitizer: Sanitizer;
|
|
45
46
|
readonly debug: Logger;
|
|
46
47
|
readonly notify: Logger;
|
|
48
|
+
readonly session: Session;
|
|
47
49
|
private readonly messages;
|
|
48
50
|
private readonly observer;
|
|
49
51
|
private readonly startCallbacks;
|
|
@@ -51,18 +53,16 @@ export default class App {
|
|
|
51
53
|
private readonly commitCallbacks;
|
|
52
54
|
private readonly options;
|
|
53
55
|
private readonly revID;
|
|
54
|
-
private _sessionID;
|
|
55
|
-
private _userID;
|
|
56
|
-
private _metadata;
|
|
57
56
|
private activityState;
|
|
58
57
|
private version;
|
|
59
58
|
private readonly worker?;
|
|
60
59
|
constructor(projectKey: string, sessionToken: string | null | undefined, options: Partial<Options>);
|
|
61
60
|
private _debug;
|
|
61
|
+
private readonly preStartMessages;
|
|
62
62
|
send(message: Message, urgent?: boolean): void;
|
|
63
63
|
private commit;
|
|
64
|
-
attachCommitCallback(cb: CommitCallback): void;
|
|
65
64
|
safe<T extends (...args: any[]) => void>(fn: T): T;
|
|
65
|
+
attachCommitCallback(cb: CommitCallback): void;
|
|
66
66
|
attachStartCallback(cb: Callback): void;
|
|
67
67
|
attachStopCallback(cb: Callback): void;
|
|
68
68
|
attachEventListener(target: EventTarget, type: string, listener: EventListener, useSafe?: boolean, useCapture?: boolean): void;
|
|
@@ -74,10 +74,10 @@ export default class App {
|
|
|
74
74
|
revID: string;
|
|
75
75
|
timestamp: number;
|
|
76
76
|
trackerVersion: string;
|
|
77
|
-
userID: string | null;
|
|
78
77
|
isSnippet: boolean;
|
|
79
78
|
sessionID: string | null;
|
|
80
79
|
metadata: Record<string, string>;
|
|
80
|
+
userID: string | null;
|
|
81
81
|
};
|
|
82
82
|
getSessionToken(): string | undefined;
|
|
83
83
|
getSessionID(): string | undefined;
|
package/lib/app/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { timestamp } from "../utils.js";
|
|
2
|
-
import { Timestamp
|
|
2
|
+
import { Timestamp } 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
7
|
import Logger, { LogLevel } from "./logger.js";
|
|
8
|
+
import Session from "./session.js";
|
|
8
9
|
import { deviceMemory, jsHeapSizeLimit } from "../modules/performance.js";
|
|
9
10
|
var ActivityState;
|
|
10
11
|
(function (ActivityState) {
|
|
@@ -24,11 +25,9 @@ export default class App {
|
|
|
24
25
|
this.startCallbacks = [];
|
|
25
26
|
this.stopCallbacks = [];
|
|
26
27
|
this.commitCallbacks = [];
|
|
27
|
-
this._sessionID = null;
|
|
28
|
-
this._userID = null;
|
|
29
|
-
this._metadata = {};
|
|
30
28
|
this.activityState = ActivityState.NotActive;
|
|
31
|
-
this.version = '3.5.
|
|
29
|
+
this.version = '3.5.3'; // TODO: version compatability check inside each plugin.
|
|
30
|
+
this.preStartMessages = [];
|
|
32
31
|
this.projectKey = projectKey;
|
|
33
32
|
this.options = Object.assign({
|
|
34
33
|
revID: '',
|
|
@@ -54,25 +53,20 @@ export default class App {
|
|
|
54
53
|
this.ticker.attach(() => this.commit());
|
|
55
54
|
this.debug = new Logger(this.options.__debug__);
|
|
56
55
|
this.notify = new Logger(this.options.verbose ? LogLevel.Warnings : LogLevel.Silent);
|
|
56
|
+
this.session = new Session(this);
|
|
57
57
|
try {
|
|
58
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()};
|
|
59
59
|
`], { type: 'text/javascript' })));
|
|
60
60
|
this.worker.onerror = e => {
|
|
61
61
|
this._debug("webworker_error", e);
|
|
62
62
|
};
|
|
63
|
-
let lastTs = timestamp();
|
|
64
|
-
let fileno = 0;
|
|
65
63
|
this.worker.onmessage = ({ data }) => {
|
|
66
64
|
if (data === null) {
|
|
67
65
|
this.stop();
|
|
68
66
|
}
|
|
69
67
|
else if (data === "restart") {
|
|
70
68
|
this.stop();
|
|
71
|
-
this.start({
|
|
72
|
-
forceNew: true,
|
|
73
|
-
userID: this._userID || undefined,
|
|
74
|
-
metadata: this._metadata || undefined,
|
|
75
|
-
});
|
|
69
|
+
this.start({ forceNew: true });
|
|
76
70
|
}
|
|
77
71
|
};
|
|
78
72
|
const alertWorker = () => {
|
|
@@ -103,9 +97,16 @@ export default class App {
|
|
|
103
97
|
this.debug.error("OpenReplay error: ", context, e);
|
|
104
98
|
}
|
|
105
99
|
send(message, urgent = false) {
|
|
106
|
-
if (this.activityState
|
|
100
|
+
if (this.activityState === ActivityState.NotActive) {
|
|
107
101
|
return;
|
|
108
102
|
}
|
|
103
|
+
if (this.activityState === ActivityState.Starting) {
|
|
104
|
+
this.preStartMessages.push(message);
|
|
105
|
+
}
|
|
106
|
+
if (this.preStartMessages.length) {
|
|
107
|
+
this.messages.push(...this.preStartMessages);
|
|
108
|
+
this.preStartMessages.length = 0;
|
|
109
|
+
}
|
|
109
110
|
this.messages.push(message);
|
|
110
111
|
if (urgent) {
|
|
111
112
|
this.commit();
|
|
@@ -119,9 +120,6 @@ export default class App {
|
|
|
119
120
|
this.messages.length = 0;
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
|
-
attachCommitCallback(cb) {
|
|
123
|
-
this.commitCallbacks.push(cb);
|
|
124
|
-
}
|
|
125
123
|
safe(fn) {
|
|
126
124
|
const app = this;
|
|
127
125
|
return function (...args) {
|
|
@@ -137,6 +135,9 @@ export default class App {
|
|
|
137
135
|
}
|
|
138
136
|
}; // TODO: correct typing
|
|
139
137
|
}
|
|
138
|
+
attachCommitCallback(cb) {
|
|
139
|
+
this.commitCallbacks.push(cb);
|
|
140
|
+
}
|
|
140
141
|
attachStartCallback(cb) {
|
|
141
142
|
this.startCallbacks.push(cb);
|
|
142
143
|
}
|
|
@@ -167,12 +168,11 @@ export default class App {
|
|
|
167
168
|
revID: this.revID,
|
|
168
169
|
timestamp: timestamp(),
|
|
169
170
|
trackerVersion: this.version,
|
|
170
|
-
userID: this._userID,
|
|
171
171
|
isSnippet: this.options.__is_snippet,
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
getSessionInfo() {
|
|
175
|
-
return Object.assign({
|
|
175
|
+
return Object.assign(Object.assign({}, this.session.getInfo()), this.getStartInfo());
|
|
176
176
|
}
|
|
177
177
|
getSessionToken() {
|
|
178
178
|
const token = sessionStorage.getItem(this.options.session_token_key);
|
|
@@ -181,7 +181,7 @@ export default class App {
|
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
getSessionID() {
|
|
184
|
-
return this.
|
|
184
|
+
return this.session.getInfo().sessionID || undefined;
|
|
185
185
|
}
|
|
186
186
|
getHost() {
|
|
187
187
|
return new URL(this.options.ingestPoint).hostname;
|
|
@@ -238,8 +238,6 @@ export default class App {
|
|
|
238
238
|
pageNo++;
|
|
239
239
|
}
|
|
240
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
241
|
const startInfo = this.getStartInfo();
|
|
244
242
|
const messageData = {
|
|
245
243
|
ingestPoint: this.options.ingestPoint,
|
|
@@ -256,7 +254,7 @@ export default class App {
|
|
|
256
254
|
headers: {
|
|
257
255
|
'Content-Type': 'application/json',
|
|
258
256
|
},
|
|
259
|
-
body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { token: sessionStorage.getItem(this.options.session_token_key), deviceMemory,
|
|
257
|
+
body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { userID: startOpts.userID || this.session.getInfo().userID, token: sessionStorage.getItem(this.options.session_token_key), deviceMemory,
|
|
260
258
|
jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
|
|
261
259
|
})
|
|
262
260
|
.then(r => {
|
|
@@ -265,7 +263,7 @@ export default class App {
|
|
|
265
263
|
}
|
|
266
264
|
else {
|
|
267
265
|
return r.text().then(text => text === CANCELED
|
|
268
|
-
? Promise.reject(CANCELED)
|
|
266
|
+
? Promise.reject(CANCELED) // TODO: return {error: CANCELED} instead
|
|
269
267
|
: Promise.reject(`Server error: ${r.status}. ${text}`));
|
|
270
268
|
}
|
|
271
269
|
})
|
|
@@ -281,15 +279,12 @@ export default class App {
|
|
|
281
279
|
}
|
|
282
280
|
sessionStorage.setItem(this.options.session_token_key, token);
|
|
283
281
|
localStorage.setItem(this.options.local_uuid_key, userUUID);
|
|
284
|
-
|
|
285
|
-
this._sessionID = sessionID;
|
|
286
|
-
}
|
|
282
|
+
this.session.update(Object.assign({ sessionID }, startOpts));
|
|
287
283
|
this.activityState = ActivityState.Active;
|
|
288
284
|
this.worker.postMessage({ token, beaconSizeLimit });
|
|
289
285
|
this.startCallbacks.forEach((cb) => cb());
|
|
290
286
|
this.observer.observe();
|
|
291
287
|
this.ticker.start();
|
|
292
|
-
Object.entries(this._metadata).forEach(([key, value]) => this.send(new Metadata(key, value)));
|
|
293
288
|
this.notify.log("OpenReplay tracking started.");
|
|
294
289
|
// TODO: get rid of onStart
|
|
295
290
|
const onStartInfo = { sessionToken: token, userUUID, sessionID };
|
package/lib/app/logger.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare const LogLevel: {
|
|
2
|
-
readonly Verbose:
|
|
3
|
-
readonly
|
|
2
|
+
readonly Verbose: 5;
|
|
3
|
+
readonly Log: 4;
|
|
4
4
|
readonly Warnings: 3;
|
|
5
|
-
readonly
|
|
5
|
+
readonly Errors: 2;
|
|
6
6
|
readonly Silent: 0;
|
|
7
7
|
};
|
|
8
8
|
declare type LogLevel = typeof LogLevel[keyof typeof LogLevel];
|
|
@@ -18,7 +18,6 @@ interface _Options {
|
|
|
18
18
|
export declare type Options = true | _Options | LogLevel;
|
|
19
19
|
export default class Logger {
|
|
20
20
|
private readonly options;
|
|
21
|
-
private readonly opts;
|
|
22
21
|
constructor(options?: Options);
|
|
23
22
|
log(...args: any): void;
|
|
24
23
|
warn(...args: any): void;
|
package/lib/app/logger.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const LogLevel = {
|
|
2
|
-
Verbose:
|
|
3
|
-
|
|
2
|
+
Verbose: 5,
|
|
3
|
+
Log: 4,
|
|
4
4
|
Warnings: 3,
|
|
5
|
-
|
|
5
|
+
Errors: 2,
|
|
6
6
|
Silent: 0,
|
|
7
7
|
};
|
|
8
8
|
function IsCustomLevel(l) {
|
|
@@ -10,29 +10,28 @@ function IsCustomLevel(l) {
|
|
|
10
10
|
}
|
|
11
11
|
export default class Logger {
|
|
12
12
|
constructor(options = LogLevel.Silent) {
|
|
13
|
-
this.options = options
|
|
14
|
-
this.opts = options === true
|
|
13
|
+
this.options = options === true
|
|
15
14
|
? { level: LogLevel.Verbose }
|
|
16
15
|
: typeof options === "number" ? { level: options } : options;
|
|
17
16
|
}
|
|
18
17
|
log(...args) {
|
|
19
|
-
if (IsCustomLevel(this.
|
|
20
|
-
? this.
|
|
21
|
-
: this.
|
|
18
|
+
if (IsCustomLevel(this.options.level)
|
|
19
|
+
? this.options.level.log
|
|
20
|
+
: this.options.level >= LogLevel.Log) {
|
|
22
21
|
console.log(...args);
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
warn(...args) {
|
|
26
|
-
if (IsCustomLevel(this.
|
|
27
|
-
? this.
|
|
28
|
-
: this.
|
|
25
|
+
if (IsCustomLevel(this.options.level)
|
|
26
|
+
? this.options.level.warn
|
|
27
|
+
: this.options.level >= LogLevel.Warnings) {
|
|
29
28
|
console.warn(...args);
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
error(...args) {
|
|
33
|
-
if (IsCustomLevel(this.
|
|
34
|
-
? this.
|
|
35
|
-
: this.
|
|
32
|
+
if (IsCustomLevel(this.options.level)
|
|
33
|
+
? this.options.level.error
|
|
34
|
+
: this.options.level >= LogLevel.Errors) {
|
|
36
35
|
console.error(...args);
|
|
37
36
|
}
|
|
38
37
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import App from "./index.js";
|
|
2
|
+
interface SessionInfo {
|
|
3
|
+
sessionID: string | null;
|
|
4
|
+
metadata: Record<string, string>;
|
|
5
|
+
userID: string | null;
|
|
6
|
+
}
|
|
7
|
+
declare type OnUpdateCallback = (i: Partial<SessionInfo>) => void;
|
|
8
|
+
export default class Session {
|
|
9
|
+
private app;
|
|
10
|
+
private metadata;
|
|
11
|
+
private userID;
|
|
12
|
+
private sessionID;
|
|
13
|
+
private activityState;
|
|
14
|
+
private callbacks;
|
|
15
|
+
constructor(app: App);
|
|
16
|
+
attachUpdateCallback(cb: OnUpdateCallback): void;
|
|
17
|
+
private handleUpdate;
|
|
18
|
+
update({ userID, metadata, sessionID }: Partial<SessionInfo>): void;
|
|
19
|
+
private _setMetadata;
|
|
20
|
+
private _setUserID;
|
|
21
|
+
setMetadata(key: string, value: string): void;
|
|
22
|
+
setUserID(userID: string): void;
|
|
23
|
+
getInfo(): SessionInfo;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { UserID, Metadata } from "../messages/index.js";
|
|
2
|
+
var ActivityState;
|
|
3
|
+
(function (ActivityState) {
|
|
4
|
+
ActivityState[ActivityState["NotActive"] = 0] = "NotActive";
|
|
5
|
+
ActivityState[ActivityState["Starting"] = 1] = "Starting";
|
|
6
|
+
ActivityState[ActivityState["Active"] = 2] = "Active";
|
|
7
|
+
})(ActivityState || (ActivityState = {}));
|
|
8
|
+
export default class Session {
|
|
9
|
+
constructor(app) {
|
|
10
|
+
this.app = app;
|
|
11
|
+
this.metadata = {};
|
|
12
|
+
this.userID = null;
|
|
13
|
+
this.sessionID = null;
|
|
14
|
+
this.activityState = ActivityState.NotActive;
|
|
15
|
+
this.callbacks = [];
|
|
16
|
+
}
|
|
17
|
+
attachUpdateCallback(cb) {
|
|
18
|
+
this.callbacks.push(cb);
|
|
19
|
+
}
|
|
20
|
+
handleUpdate() {
|
|
21
|
+
const sessInfo = this.getInfo();
|
|
22
|
+
if (sessInfo.userID == null) {
|
|
23
|
+
delete sessInfo.userID;
|
|
24
|
+
}
|
|
25
|
+
if (sessInfo.sessionID == null) {
|
|
26
|
+
delete sessInfo.sessionID;
|
|
27
|
+
}
|
|
28
|
+
this.callbacks.forEach(cb => cb(sessInfo));
|
|
29
|
+
}
|
|
30
|
+
update({ userID, metadata, sessionID }) {
|
|
31
|
+
if (userID != null) { // TODO clear nullable/undefinable types
|
|
32
|
+
this._setUserID(userID);
|
|
33
|
+
}
|
|
34
|
+
if (metadata !== undefined) {
|
|
35
|
+
Object.entries(metadata).forEach(kv => this._setMetadata(...kv));
|
|
36
|
+
}
|
|
37
|
+
if (sessionID !== undefined) {
|
|
38
|
+
this.sessionID = sessionID;
|
|
39
|
+
}
|
|
40
|
+
this.handleUpdate();
|
|
41
|
+
}
|
|
42
|
+
_setMetadata(key, value) {
|
|
43
|
+
this.app.send(new Metadata(key, value));
|
|
44
|
+
this.metadata[key] = value;
|
|
45
|
+
}
|
|
46
|
+
_setUserID(userID) {
|
|
47
|
+
this.app.send(new UserID(userID));
|
|
48
|
+
this.userID = userID;
|
|
49
|
+
}
|
|
50
|
+
setMetadata(key, value) {
|
|
51
|
+
this._setMetadata(key, value);
|
|
52
|
+
this.handleUpdate();
|
|
53
|
+
}
|
|
54
|
+
setUserID(userID) {
|
|
55
|
+
this._setUserID(userID);
|
|
56
|
+
this.handleUpdate();
|
|
57
|
+
}
|
|
58
|
+
getInfo() {
|
|
59
|
+
return {
|
|
60
|
+
sessionID: this.sessionID,
|
|
61
|
+
metadata: this.metadata,
|
|
62
|
+
userID: this.userID,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import App, { DEFAULT_INGEST_POINT } from "./app/index.js";
|
|
2
2
|
export { default as App } from './app/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { UserAnonymousID, RawCustomEvent, CustomIssue } from "./messages/index.js";
|
|
4
4
|
import * as _Messages from "./messages/index.js";
|
|
5
5
|
export const Messages = _Messages;
|
|
6
6
|
import Connection from "./modules/connection.js";
|
|
@@ -13,7 +13,6 @@ import Timing from "./modules/timing.js";
|
|
|
13
13
|
import Performance from "./modules/performance.js";
|
|
14
14
|
import Scroll from "./modules/scroll.js";
|
|
15
15
|
import Viewport from "./modules/viewport.js";
|
|
16
|
-
import Longtasks from "./modules/longtasks.js";
|
|
17
16
|
import CSSRules from "./modules/cssrules.js";
|
|
18
17
|
import { IN_BROWSER, deprecationWarn, DOCS_HOST } from "./utils.js";
|
|
19
18
|
const DOCS_SETUP = '/installation/setup-or';
|
|
@@ -100,7 +99,6 @@ export default class API {
|
|
|
100
99
|
Timing(app, options);
|
|
101
100
|
Performance(app, options);
|
|
102
101
|
Scroll(app);
|
|
103
|
-
Longtasks(app);
|
|
104
102
|
window.__OPENREPLAY__ = this;
|
|
105
103
|
if (options.autoResetOnWindowOpen) {
|
|
106
104
|
const wOpen = window.open;
|
|
@@ -125,7 +123,7 @@ export default class API {
|
|
|
125
123
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
126
124
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
127
125
|
req.send(JSON.stringify({
|
|
128
|
-
trackerVersion: '3.5.
|
|
126
|
+
trackerVersion: '3.5.3',
|
|
129
127
|
projectKey: options.projectKey,
|
|
130
128
|
doNotTrack,
|
|
131
129
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -176,7 +174,7 @@ export default class API {
|
|
|
176
174
|
}
|
|
177
175
|
setUserID(id) {
|
|
178
176
|
if (typeof id === 'string' && this.app !== null) {
|
|
179
|
-
this.app.
|
|
177
|
+
this.app.session.setUserID(id);
|
|
180
178
|
}
|
|
181
179
|
}
|
|
182
180
|
userID(id) {
|
|
@@ -196,7 +194,7 @@ export default class API {
|
|
|
196
194
|
if (typeof key === 'string' &&
|
|
197
195
|
typeof value === 'string' &&
|
|
198
196
|
this.app !== null) {
|
|
199
|
-
this.app.
|
|
197
|
+
this.app.session.setMetadata(key, value);
|
|
200
198
|
}
|
|
201
199
|
}
|
|
202
200
|
metadata(key, value) {
|