@openreplay/tracker 3.5.16 → 3.5.17-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +8 -0
- package/cjs/app/guards.js +1 -2
- package/cjs/app/index.d.ts +14 -14
- package/cjs/app/index.js +51 -44
- package/cjs/app/logger.js +6 -3
- package/cjs/app/observer/iframe_observer.d.ts +1 -1
- package/cjs/app/observer/iframe_observer.js +1 -1
- package/cjs/app/observer/observer.d.ts +1 -1
- package/cjs/app/observer/observer.js +12 -15
- package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
- package/cjs/app/observer/shadow_root_observer.js +1 -1
- package/cjs/app/observer/top_observer.d.ts +2 -2
- package/cjs/app/observer/top_observer.js +12 -11
- package/cjs/app/sanitizer.d.ts +1 -1
- package/cjs/app/sanitizer.js +5 -5
- package/cjs/app/session.d.ts +1 -1
- package/cjs/app/session.js +4 -3
- package/cjs/app/ticker.d.ts +1 -1
- package/cjs/common/webworker.d.ts +3 -3
- package/cjs/index.d.ts +8 -8
- package/cjs/index.js +27 -27
- package/cjs/modules/connection.d.ts +1 -1
- package/cjs/modules/console.d.ts +1 -1
- package/cjs/modules/console.js +5 -5
- package/cjs/modules/cssrules.d.ts +1 -1
- package/cjs/modules/cssrules.js +3 -3
- package/cjs/modules/exception.d.ts +2 -2
- package/cjs/modules/exception.js +7 -6
- package/cjs/modules/img.d.ts +1 -1
- package/cjs/modules/img.js +15 -12
- package/cjs/modules/input.d.ts +1 -1
- package/cjs/modules/input.js +15 -15
- package/cjs/modules/longtasks.d.ts +1 -1
- package/cjs/modules/longtasks.js +13 -5
- package/cjs/modules/mouse.d.ts +1 -1
- package/cjs/modules/mouse.js +10 -12
- package/cjs/modules/performance.d.ts +1 -1
- package/cjs/modules/scroll.d.ts +1 -1
- package/cjs/modules/timing.d.ts +1 -1
- package/cjs/modules/timing.js +12 -24
- package/cjs/modules/viewport.d.ts +1 -1
- package/cjs/utils.js +7 -7
- package/cjs/vendors/finder/finder.js +53 -48
- package/lib/app/guards.js +1 -2
- package/lib/app/index.d.ts +14 -14
- package/lib/app/index.js +60 -53
- package/lib/app/logger.js +6 -3
- package/lib/app/observer/iframe_observer.d.ts +1 -1
- package/lib/app/observer/iframe_observer.js +3 -3
- package/lib/app/observer/observer.d.ts +1 -1
- package/lib/app/observer/observer.js +14 -17
- package/lib/app/observer/shadow_root_observer.d.ts +1 -1
- package/lib/app/observer/shadow_root_observer.js +3 -3
- package/lib/app/observer/top_observer.d.ts +2 -2
- package/lib/app/observer/top_observer.js +17 -16
- package/lib/app/sanitizer.d.ts +1 -1
- package/lib/app/sanitizer.js +7 -7
- package/lib/app/session.d.ts +1 -1
- package/lib/app/session.js +4 -3
- package/lib/app/ticker.d.ts +1 -1
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/common/webworker.d.ts +3 -3
- package/lib/index.d.ts +8 -8
- package/lib/index.js +42 -42
- package/lib/modules/connection.d.ts +1 -1
- package/lib/modules/connection.js +1 -1
- package/lib/modules/console.d.ts +1 -1
- package/lib/modules/console.js +8 -8
- package/lib/modules/cssrules.d.ts +1 -1
- package/lib/modules/cssrules.js +5 -5
- package/lib/modules/exception.d.ts +2 -2
- package/lib/modules/exception.js +8 -7
- package/lib/modules/img.d.ts +1 -1
- package/lib/modules/img.js +18 -15
- package/lib/modules/input.d.ts +1 -1
- package/lib/modules/input.js +18 -18
- package/lib/modules/longtasks.d.ts +1 -1
- package/lib/modules/longtasks.js +14 -6
- package/lib/modules/mouse.d.ts +1 -1
- package/lib/modules/mouse.js +14 -16
- package/lib/modules/performance.d.ts +1 -1
- package/lib/modules/performance.js +2 -2
- package/lib/modules/scroll.d.ts +1 -1
- package/lib/modules/scroll.js +2 -2
- package/lib/modules/timing.d.ts +1 -1
- package/lib/modules/timing.js +15 -27
- package/lib/modules/viewport.d.ts +1 -1
- package/lib/modules/viewport.js +1 -1
- package/lib/utils.js +7 -7
- package/lib/vendors/finder/finder.js +53 -48
- package/package.json +27 -10
package/lib/app/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Timestamp, Metadata, UserID } from
|
|
2
|
-
import { timestamp } from
|
|
3
|
-
import Nodes from
|
|
4
|
-
import Observer from
|
|
5
|
-
import Sanitizer from
|
|
6
|
-
import Ticker from
|
|
7
|
-
import Logger, { LogLevel } from
|
|
8
|
-
import Session from
|
|
9
|
-
import { deviceMemory, jsHeapSizeLimit } from
|
|
10
|
-
const CANCELED =
|
|
11
|
-
const START_ERROR =
|
|
1
|
+
import { Timestamp, Metadata, UserID } from '../common/messages.js';
|
|
2
|
+
import { timestamp } from '../utils.js';
|
|
3
|
+
import Nodes from './nodes.js';
|
|
4
|
+
import Observer from './observer/top_observer.js';
|
|
5
|
+
import Sanitizer from './sanitizer.js';
|
|
6
|
+
import Ticker from './ticker.js';
|
|
7
|
+
import Logger, { LogLevel } from './logger.js';
|
|
8
|
+
import Session from './session.js';
|
|
9
|
+
import { deviceMemory, jsHeapSizeLimit } from '../modules/performance.js';
|
|
10
|
+
const CANCELED = 'canceled';
|
|
11
|
+
const START_ERROR = ':(';
|
|
12
12
|
const UnsuccessfulStart = (reason) => ({ reason, success: false });
|
|
13
13
|
const SuccessfulStart = (body) => (Object.assign(Object.assign({}, body), { success: true }));
|
|
14
14
|
var ActivityState;
|
|
@@ -24,6 +24,7 @@ export default class App {
|
|
|
24
24
|
// if (options.onStart !== undefined) {
|
|
25
25
|
// deprecationWarn("'onStart' option", "tracker.start().then(/* handle session info */)")
|
|
26
26
|
// } ?? maybe onStart is good
|
|
27
|
+
var _a, _b;
|
|
27
28
|
this.messages = [];
|
|
28
29
|
this.startCallbacks = [];
|
|
29
30
|
this.stopCallbacks = [];
|
|
@@ -43,8 +44,8 @@ export default class App {
|
|
|
43
44
|
verbose: false,
|
|
44
45
|
__is_snippet: false,
|
|
45
46
|
__debug_report_edp: null,
|
|
46
|
-
localStorage:
|
|
47
|
-
sessionStorage:
|
|
47
|
+
localStorage: null,
|
|
48
|
+
sessionStorage: null,
|
|
48
49
|
}, options);
|
|
49
50
|
this.revID = this.options.revID;
|
|
50
51
|
this.sanitizer = new Sanitizer(this, options);
|
|
@@ -56,30 +57,31 @@ export default class App {
|
|
|
56
57
|
this.notify = new Logger(this.options.verbose ? LogLevel.Warnings : LogLevel.Silent);
|
|
57
58
|
this.session = new Session();
|
|
58
59
|
this.session.attachUpdateCallback(({ userID, metadata }) => {
|
|
59
|
-
if (userID != null) {
|
|
60
|
+
if (userID != null) {
|
|
61
|
+
// TODO: nullable userID
|
|
60
62
|
this.send(new UserID(userID));
|
|
61
63
|
}
|
|
62
64
|
if (metadata != null) {
|
|
63
65
|
Object.entries(metadata).forEach(([key, value]) => this.send(new Metadata(key, value)));
|
|
64
66
|
}
|
|
65
67
|
});
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
+
// window.localStorage and window.sessionStorage should only be accessed if required, see #490, #637
|
|
69
|
+
this.localStorage = (_a = this.options.localStorage) !== null && _a !== void 0 ? _a : window.localStorage;
|
|
70
|
+
this.sessionStorage = (_b = this.options.sessionStorage) !== null && _b !== void 0 ? _b : window.sessionStorage;
|
|
68
71
|
if (sessionToken != null) {
|
|
69
72
|
this.sessionStorage.setItem(this.options.session_token_key, sessionToken);
|
|
70
73
|
}
|
|
71
74
|
try {
|
|
72
|
-
this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function i(...i){return new t(...i)}return i.prototype=t.prototype,i}const i=new Map;const s=t(class{constructor(t,i,s){this.pageNo=t,this.firstIndex=i,this.timestamp=s,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});i.set(80,s);const e=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});i.set(0,e);const n=t(class{constructor(t,i,s){this.url=t,this.referrer=i,this.navigationStart=s,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});i.set(4,n);const r=t(class{constructor(t,i){this.width=t,this.height=i,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});i.set(5,r);const h=t(class{constructor(t,i){this.x=t,this.y=i,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});i.set(6,h);const o=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});i.set(7,o);const c=t(class{constructor(t,i,s,e,n){this.id=t,this.parentID=i,this.index=s,this.tag=e,this.svg=n,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});i.set(8,c);const a=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(9,a);const u=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(10,u);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});i.set(11,d);const l=t(class{constructor(t,i,s){this.id=t,this.name=i,this.value=s,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});i.set(12,l);const p=t(class{constructor(t,i){this.id=t,this.name=i,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});i.set(13,p);const g=t(class{constructor(t,i){this.id=t,this.data=i,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});i.set(14,g);const m=t(class{constructor(t,i,s){this.id=t,this.x=i,this.y=s,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});i.set(16,m);const f=t(class{constructor(t,i){this.id=t,this.label=i,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});i.set(17,f);const y=t(class{constructor(t,i,s){this.id=t,this.value=i,this.mask=s,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});i.set(18,y);const _=t(class{constructor(t,i){this.id=t,this.checked=i,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});i.set(19,_);const v=t(class{constructor(t,i){this.x=t,this.y=i,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});i.set(20,v);const S=t(class{constructor(t,i){this.level=t,this.value=i,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});i.set(22,S);const b=t(class{constructor(t,i,s,e,n,r,h,o,c){this.requestStart=t,this.responseStart=i,this.responseEnd=s,this.domContentLoadedEventStart=e,this.domContentLoadedEventEnd=n,this.loadEventStart=r,this.loadEventEnd=h,this.firstPaint=o,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});i.set(23,b);const w=t(class{constructor(t,i,s){this.speedIndex=t,this.visuallyComplete=i,this.timeToInteractive=s,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});i.set(24,w);const E=t(class{constructor(t,i,s){this.name=t,this.message=i,this.payload=s,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});i.set(25,E);const x=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});i.set(27,x);const T=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});i.set(28,T);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});i.set(29,z);const k=t(class{constructor(t,i){this.key=t,this.value=i,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});i.set(30,k);const A=t(class{constructor(t,i,s){this.id=t,this.rule=i,this.index=s,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});i.set(37,A);const I=t(class{constructor(t,i){this.id=t,this.index=i,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});i.set(38,I);const L=t(class{constructor(t,i,s,e,n,r,h){this.method=t,this.url=i,this.request=s,this.response=e,this.status=n,this.timestamp=r,this.duration=h,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});i.set(39,L);const C=t(class{constructor(t,i,s,e){this.name=t,this.duration=i,this.args=s,this.result=e,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});i.set(40,C);const M=t(class{constructor(t,i){this.key=t,this.value=i,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});i.set(41,M);const N=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});i.set(42,N);const B=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(44,B);const U=t(class{constructor(t,i){this.mutation=t,this.state=i,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});i.set(45,U);const R=t(class{constructor(t,i){this.type=t,this.payload=i,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});i.set(46,R);const O=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(47,O);const P=t(class{constructor(t,i,s,e){this.operationKind=t,this.operationName=i,this.variables=s,this.response=e,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});i.set(48,P);const q=t(class{constructor(t,i,s,e){this.frames=t,this.ticks=i,this.totalJSHeapSize=s,this.usedJSHeapSize=e,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});i.set(49,q);const D=t(class{constructor(t,i,s,e,n,r,h,o){this.timestamp=t,this.duration=i,this.ttfb=s,this.headerSize=e,this.encodedBodySize=n,this.decodedBodySize=r,this.url=h,this.initiator=o,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});i.set(53,D);const W=t(class{constructor(t,i){this.downlink=t,this.type=i,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});i.set(54,W);const H=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});i.set(55,H);const J=t(class{constructor(t,i,s,e,n,r,h){this.timestamp=t,this.duration=i,this.context=s,this.containerType=e,this.containerSrc=n,this.containerId=r,this.containerName=h,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});i.set(59,J);const F=t(class{constructor(t,i,s,e){this.id=t,this.name=i,this.value=s,this.baseURL=e,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});i.set(60,F);const X=t(class{constructor(t,i,s){this.id=t,this.data=i,this.baseURL=s,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});i.set(61,X);const G=t(class{constructor(t,i){this.type=t,this.value=i,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});i.set(63,G);const K=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});i.set(64,K);const j=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});i.set(65,j);const Q=t(class{constructor(t,i,s,e){this.id=t,this.rule=i,this.index=s,this.baseURL=e,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});i.set(67,Q);const V=t(class{constructor(t,i,s,e){this.id=t,this.hesitationTime=i,this.label=s,this.selector=e,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});i.set(69,V);const Y=t(class{constructor(t,i){this.frameID=t,this.id=i,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});i.set(70,Y);class Z{constructor(t,i,s,e=10,n=1e3){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i"}authorise(t){this.token=t}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure():(this.attemptsCount++,setTimeout(()=>this.sendBatch(t),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t){this.busy=!0,fetch(this.ingestURL,{body:t,method:"POST",headers:{Authorization:"Bearer "+this.token},keepalive:t.length<65536}).then(i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();if(i.status>=400)return void this.retry(t);this.attemptsCount=0;const s=this.queue.shift();s?this.sendBatch(s):this.busy=!1}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0}}const tt="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(var n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(!((r=t.charCodeAt(h))>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(h+=1,(n=1024*(n-55296)+r-56320+65536)>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class it{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=tt.encode(t),s=i.byteLength;return!(!this.uint(s)||this.offset+s>this.size)&&(this.data.set(i,this.offset),this.offset+=s,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class st{constructor(t,i,s){this.pageNo=t,this.timestamp=i,this.onBatch=s,this.nextIndex=0,this.beaconSize=2e5,this.writer=new it(this.beaconSize),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}prepare(){this.writer.isEmpty()&&new s(this.pageNo,this.nextIndex,this.timestamp).encode(this.writer)}write(t){const i=t.encode(this.writer);return i&&(this.isEmpty=!1,this.writer.checkpoint(),this.nextIndex++),i}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){for(t instanceof e&&(this.timestamp=t.timestamp);!this.write(t);){if(this.finaliseBatch(),this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message."),this.writer.reset(),this.prepare(),void(this.isEmpty=!0);this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.writer=new it(this.beaconSize),this.prepare(),this.isEmpty=!0}}finaliseBatch(){this.isEmpty||(this.onBatch(this.writer.flush()),this.prepare(),this.isEmpty=!0)}clean(){this.writer.reset()}}var et;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(et||(et={}));let nt=null,rt=null;function ht(){rt&&rt.finaliseBatch()}function ot(){et.Stopping,null!==at&&(clearInterval(at),at=null),rt&&(rt.clean(),rt=null),et.NotActive}et.NotActive;let ct,at=null;self.onmessage=({data:t})=>{if(null!=t){if("stop"===t)return ht(),void ot();if(Array.isArray(t)){if(!rt)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const s=rt;t.forEach(t=>{const e=new(i.get(t._id));Object.assign(e,t),e instanceof H&&(e.hidden?ct=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(ct)),s.writeMessage(e)})}else{if("start"===t.type)return et.Starting,nt=new Z(t.ingestPoint,()=>{self.postMessage("restart")},()=>{nt&&(nt.clean(),nt=null),ot(),self.postMessage("failed")},t.connAttemptCount,t.connAttemptGap),rt=new st(t.pageNo,t.timestamp,t=>nt&&nt.push(t)),null===at&&(at=setInterval(ht,1e4)),et.Active;if("auth"===t.type){if(!nt)throw new Error("WebWorker: sender not initialised. Received auth.");if(!rt)throw new Error("WebWorker: writer not initialised. Received auth.");return nt.authorise(t.token),void(t.beaconSizeLimit&&rt.setBeaconSizeLimit(t.beaconSizeLimit))}}}else ht()};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this._debug("webworker_error", e);
|
|
75
|
+
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";function t(t){function i(...i){return new t(...i)}return i.prototype=t.prototype,i}const i=new Map;const s=t(class{constructor(t,i,s){this.pageNo=t,this.firstIndex=i,this.timestamp=s,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});i.set(80,s);const e=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});i.set(0,e);const n=t(class{constructor(t,i,s){this.url=t,this.referrer=i,this.navigationStart=s,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});i.set(4,n);const r=t(class{constructor(t,i){this.width=t,this.height=i,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});i.set(5,r);const h=t(class{constructor(t,i){this.x=t,this.y=i,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});i.set(6,h);const o=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});i.set(7,o);const c=t(class{constructor(t,i,s,e,n){this.id=t,this.parentID=i,this.index=s,this.tag=e,this.svg=n,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});i.set(8,c);const a=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(9,a);const u=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(10,u);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});i.set(11,d);const l=t(class{constructor(t,i,s){this.id=t,this.name=i,this.value=s,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});i.set(12,l);const p=t(class{constructor(t,i){this.id=t,this.name=i,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});i.set(13,p);const g=t(class{constructor(t,i){this.id=t,this.data=i,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});i.set(14,g);const m=t(class{constructor(t,i,s){this.id=t,this.x=i,this.y=s,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});i.set(16,m);const f=t(class{constructor(t,i){this.id=t,this.label=i,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});i.set(17,f);const y=t(class{constructor(t,i,s){this.id=t,this.value=i,this.mask=s,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});i.set(18,y);const _=t(class{constructor(t,i){this.id=t,this.checked=i,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});i.set(19,_);const v=t(class{constructor(t,i){this.x=t,this.y=i,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});i.set(20,v);const S=t(class{constructor(t,i){this.level=t,this.value=i,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});i.set(22,S);const b=t(class{constructor(t,i,s,e,n,r,h,o,c){this.requestStart=t,this.responseStart=i,this.responseEnd=s,this.domContentLoadedEventStart=e,this.domContentLoadedEventEnd=n,this.loadEventStart=r,this.loadEventEnd=h,this.firstPaint=o,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});i.set(23,b);const w=t(class{constructor(t,i,s){this.speedIndex=t,this.visuallyComplete=i,this.timeToInteractive=s,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});i.set(24,w);const E=t(class{constructor(t,i,s){this.name=t,this.message=i,this.payload=s,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});i.set(25,E);const x=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});i.set(27,x);const T=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});i.set(28,T);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});i.set(29,z);const k=t(class{constructor(t,i){this.key=t,this.value=i,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});i.set(30,k);const A=t(class{constructor(t,i,s){this.id=t,this.rule=i,this.index=s,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});i.set(37,A);const I=t(class{constructor(t,i){this.id=t,this.index=i,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});i.set(38,I);const L=t(class{constructor(t,i,s,e,n,r,h){this.method=t,this.url=i,this.request=s,this.response=e,this.status=n,this.timestamp=r,this.duration=h,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});i.set(39,L);const C=t(class{constructor(t,i,s,e){this.name=t,this.duration=i,this.args=s,this.result=e,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});i.set(40,C);const M=t(class{constructor(t,i){this.key=t,this.value=i,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});i.set(41,M);const N=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});i.set(42,N);const B=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(44,B);const U=t(class{constructor(t,i){this.mutation=t,this.state=i,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});i.set(45,U);const R=t(class{constructor(t,i){this.type=t,this.payload=i,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});i.set(46,R);const O=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(47,O);const P=t(class{constructor(t,i,s,e){this.operationKind=t,this.operationName=i,this.variables=s,this.response=e,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});i.set(48,P);const q=t(class{constructor(t,i,s,e){this.frames=t,this.ticks=i,this.totalJSHeapSize=s,this.usedJSHeapSize=e,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});i.set(49,q);const D=t(class{constructor(t,i,s,e,n,r,h,o){this.timestamp=t,this.duration=i,this.ttfb=s,this.headerSize=e,this.encodedBodySize=n,this.decodedBodySize=r,this.url=h,this.initiator=o,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});i.set(53,D);const W=t(class{constructor(t,i){this.downlink=t,this.type=i,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});i.set(54,W);const H=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});i.set(55,H);const J=t(class{constructor(t,i,s,e,n,r,h){this.timestamp=t,this.duration=i,this.context=s,this.containerType=e,this.containerSrc=n,this.containerId=r,this.containerName=h,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});i.set(59,J);const F=t(class{constructor(t,i,s,e){this.id=t,this.name=i,this.value=s,this.baseURL=e,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});i.set(60,F);const X=t(class{constructor(t,i,s){this.id=t,this.data=i,this.baseURL=s,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});i.set(61,X);const G=t(class{constructor(t,i){this.type=t,this.value=i,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});i.set(63,G);const K=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});i.set(64,K);const j=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});i.set(65,j);const Q=t(class{constructor(t,i,s,e){this.id=t,this.rule=i,this.index=s,this.baseURL=e,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});i.set(67,Q);const V=t(class{constructor(t,i,s,e){this.id=t,this.hesitationTime=i,this.label=s,this.selector=e,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});i.set(69,V);const Y=t(class{constructor(t,i){this.frameID=t,this.id=i,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});i.set(70,Y);class Z{constructor(t,i,s,e=10,n=1e3){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i"}authorise(t){this.token=t}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure():(this.attemptsCount++,setTimeout(()=>this.sendBatch(t),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t){this.busy=!0,fetch(this.ingestURL,{body:t,method:"POST",headers:{Authorization:"Bearer "+this.token},keepalive:t.length<65536}).then(i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();if(i.status>=400)return void this.retry(t);this.attemptsCount=0;const s=this.queue.shift();s?this.sendBatch(s):this.busy=!1}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0}}const tt="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(let n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(r=t.charCodeAt(h),!(r>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(n=1024*(n-55296)+r-56320+65536,h+=1,n>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class it{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=tt.encode(t),s=i.byteLength;return!(!this.uint(s)||this.offset+s>this.size)&&(this.data.set(i,this.offset),this.offset+=s,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class st{constructor(t,i,s){this.pageNo=t,this.timestamp=i,this.onBatch=s,this.nextIndex=0,this.beaconSize=2e5,this.writer=new it(this.beaconSize),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}prepare(){this.writer.isEmpty()&&new s(this.pageNo,this.nextIndex,this.timestamp).encode(this.writer)}write(t){const i=t.encode(this.writer);return i&&(this.isEmpty=!1,this.writer.checkpoint(),this.nextIndex++),i}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if(t instanceof e&&(this.timestamp=t.timestamp),!this.write(t))for(this.finaliseBatch();!this.write(t);){if(this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message."),this.writer.reset(),this.prepare(),void(this.isEmpty=!0);this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.writer=new it(this.beaconSize),this.prepare(),this.isEmpty=!0}}finaliseBatch(){this.isEmpty||(this.onBatch(this.writer.flush()),this.prepare(),this.isEmpty=!0)}clean(){this.writer.reset()}}var et;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(et||(et={}));let nt=null,rt=null;function ht(){rt&&rt.finaliseBatch()}function ot(){et.Stopping,null!==at&&(clearInterval(at),at=null),rt&&(rt.clean(),rt=null),et.NotActive}et.NotActive;let ct,at=null;self.onmessage=({data:t})=>{if(null!=t){if("stop"===t)return ht(),void ot();if(Array.isArray(t)){if(!rt)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const s=rt;t.forEach(t=>{const e=new(i.get(t._id));Object.assign(e,t),e instanceof H&&(e.hidden?ct=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(ct)),s.writeMessage(e)})}else{if("start"===t.type)return et.Starting,nt=new Z(t.ingestPoint,()=>{self.postMessage("restart")},()=>{nt&&(nt.clean(),nt=null),ot(),self.postMessage("failed")},t.connAttemptCount,t.connAttemptGap),rt=new st(t.pageNo,t.timestamp,t=>nt&&nt.push(t)),null===at&&(at=setInterval(ht,1e4)),et.Active;if("auth"===t.type){if(!nt)throw new Error("WebWorker: sender not initialised. Received auth.");if(!rt)throw new Error("WebWorker: writer not initialised. Received auth.");return nt.authorise(t.token),void(t.beaconSizeLimit&&rt.setBeaconSizeLimit(t.beaconSizeLimit))}}}else ht()};'], { type: 'text/javascript' })));
|
|
76
|
+
this.worker.onerror = (e) => {
|
|
77
|
+
this._debug('webworker_error', e);
|
|
76
78
|
};
|
|
77
79
|
this.worker.onmessage = ({ data }) => {
|
|
78
|
-
if (data ===
|
|
80
|
+
if (data === 'failed') {
|
|
79
81
|
this.stop();
|
|
80
|
-
this._debug(
|
|
82
|
+
this._debug('worker_failed', {}); // add context (from worker)
|
|
81
83
|
}
|
|
82
|
-
else if (data ===
|
|
84
|
+
else if (data === 'restart') {
|
|
83
85
|
this.stop();
|
|
84
86
|
this.start({ forceNew: true });
|
|
85
87
|
}
|
|
@@ -96,7 +98,7 @@ export default class App {
|
|
|
96
98
|
this.attachEventListener(document, 'visibilitychange', alertWorker, false);
|
|
97
99
|
}
|
|
98
100
|
catch (e) {
|
|
99
|
-
this._debug(
|
|
101
|
+
this._debug('worker_start', e);
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
104
|
_debug(context, e) {
|
|
@@ -106,20 +108,20 @@ export default class App {
|
|
|
106
108
|
headers: { 'Content-Type': 'application/json' },
|
|
107
109
|
body: JSON.stringify({
|
|
108
110
|
context,
|
|
109
|
-
error: `${e}
|
|
110
|
-
})
|
|
111
|
+
error: `${e}`,
|
|
112
|
+
}),
|
|
111
113
|
});
|
|
112
114
|
}
|
|
113
|
-
this.debug.error(
|
|
115
|
+
this.debug.error('OpenReplay error: ', context, e);
|
|
114
116
|
}
|
|
115
117
|
send(message, urgent = false) {
|
|
116
118
|
if (this.activityState === ActivityState.NotActive) {
|
|
117
119
|
return;
|
|
118
120
|
}
|
|
119
121
|
this.messages.push(message);
|
|
120
|
-
// TODO: commit on start if there were `urgent` sends;
|
|
122
|
+
// TODO: commit on start if there were `urgent` sends;
|
|
121
123
|
// Clearify where urgent can be used for;
|
|
122
|
-
// Clearify workflow for each type of message in case it was sent before start
|
|
124
|
+
// Clearify workflow for each type of message in case it was sent before start
|
|
123
125
|
// (like Fetch before start; maybe add an option "preCapture: boolean" or sth alike)
|
|
124
126
|
if (this.activityState === ActivityState.Active && urgent) {
|
|
125
127
|
this.commit();
|
|
@@ -129,7 +131,7 @@ export default class App {
|
|
|
129
131
|
if (this.worker && this.messages.length) {
|
|
130
132
|
this.messages.unshift(new Timestamp(timestamp()));
|
|
131
133
|
this.worker.postMessage(this.messages);
|
|
132
|
-
this.commitCallbacks.forEach(cb => cb(this.messages));
|
|
134
|
+
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
133
135
|
this.messages.length = 0;
|
|
134
136
|
}
|
|
135
137
|
}
|
|
@@ -140,7 +142,7 @@ export default class App {
|
|
|
140
142
|
fn.apply(this, args);
|
|
141
143
|
}
|
|
142
144
|
catch (e) {
|
|
143
|
-
app._debug(
|
|
145
|
+
app._debug('safe_fn_call', e);
|
|
144
146
|
// time: timestamp(),
|
|
145
147
|
// name: e.name,
|
|
146
148
|
// message: e.message,
|
|
@@ -215,12 +217,13 @@ export default class App {
|
|
|
215
217
|
return document.baseURI;
|
|
216
218
|
}
|
|
217
219
|
// IE only
|
|
218
|
-
return ((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName(
|
|
220
|
+
return (((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName('base')[0]) === null || _b === void 0 ? void 0 : _b.getAttribute('href')) ||
|
|
221
|
+
location.origin + location.pathname);
|
|
219
222
|
}
|
|
220
223
|
resolveResourceURL(resourceURL) {
|
|
221
224
|
const base = new URL(this.getBaseHref());
|
|
222
|
-
base.pathname +=
|
|
223
|
-
base.pathname.replace(/\/+/g,
|
|
225
|
+
base.pathname += '/' + new URL(resourceURL).pathname;
|
|
226
|
+
base.pathname.replace(/\/+/g, '/');
|
|
224
227
|
return base.toString();
|
|
225
228
|
}
|
|
226
229
|
isServiceURL(url) {
|
|
@@ -239,10 +242,10 @@ export default class App {
|
|
|
239
242
|
}
|
|
240
243
|
_start(startOpts) {
|
|
241
244
|
if (!this.worker) {
|
|
242
|
-
return Promise.resolve(UnsuccessfulStart(
|
|
245
|
+
return Promise.resolve(UnsuccessfulStart('No worker found: perhaps, CSP is not set.'));
|
|
243
246
|
}
|
|
244
247
|
if (this.activityState !== ActivityState.NotActive) {
|
|
245
|
-
return Promise.resolve(UnsuccessfulStart(
|
|
248
|
+
return Promise.resolve(UnsuccessfulStart('OpenReplay: trying to call `start()` on the instance that has been started already.'));
|
|
246
249
|
}
|
|
247
250
|
this.activityState = ActivityState.Starting;
|
|
248
251
|
let pageNo = 0;
|
|
@@ -254,7 +257,7 @@ export default class App {
|
|
|
254
257
|
this.sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
|
|
255
258
|
const startInfo = this.getStartInfo();
|
|
256
259
|
const startWorkerMsg = {
|
|
257
|
-
type:
|
|
260
|
+
type: 'start',
|
|
258
261
|
pageNo,
|
|
259
262
|
ingestPoint: this.options.ingestPoint,
|
|
260
263
|
timestamp: startInfo.timestamp,
|
|
@@ -263,14 +266,16 @@ export default class App {
|
|
|
263
266
|
};
|
|
264
267
|
this.worker.postMessage(startWorkerMsg);
|
|
265
268
|
this.session.update({
|
|
266
|
-
// "
|
|
269
|
+
// TODO: transparent "session" module logic AND explicit internal api for plugins.
|
|
270
|
+
// "updating" with old metadata in order to trigger session's UpdateCallbacks.
|
|
267
271
|
// (for the case of internal .start() calls, like on "restart" webworker signal or assistent connection in tracker-assist )
|
|
268
272
|
metadata: startOpts.metadata || this.session.getInfo().metadata,
|
|
269
273
|
userID: startOpts.userID,
|
|
270
274
|
});
|
|
271
275
|
const sReset = this.sessionStorage.getItem(this.options.session_reset_key);
|
|
272
276
|
this.sessionStorage.removeItem(this.options.session_reset_key);
|
|
273
|
-
return window
|
|
277
|
+
return window
|
|
278
|
+
.fetch(this.options.ingestPoint + '/v1/web/start', {
|
|
274
279
|
method: 'POST',
|
|
275
280
|
headers: {
|
|
276
281
|
'Content-Type': 'application/json',
|
|
@@ -278,19 +283,21 @@ export default class App {
|
|
|
278
283
|
body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { userID: this.session.getInfo().userID, token: this.sessionStorage.getItem(this.options.session_token_key), deviceMemory,
|
|
279
284
|
jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
|
|
280
285
|
})
|
|
281
|
-
.then(r => {
|
|
286
|
+
.then((r) => {
|
|
282
287
|
if (r.status === 200) {
|
|
283
288
|
return r.json();
|
|
284
289
|
}
|
|
285
290
|
else {
|
|
286
|
-
return r
|
|
291
|
+
return r
|
|
292
|
+
.text()
|
|
293
|
+
.then((text) => text === CANCELED
|
|
287
294
|
? Promise.reject(CANCELED)
|
|
288
295
|
: Promise.reject(`Server error: ${r.status}. ${text}`));
|
|
289
296
|
}
|
|
290
297
|
})
|
|
291
|
-
.then(r => {
|
|
298
|
+
.then((r) => {
|
|
292
299
|
if (!this.worker) {
|
|
293
|
-
return Promise.reject(
|
|
300
|
+
return Promise.reject('no worker found after start request (this might not happen)');
|
|
294
301
|
}
|
|
295
302
|
const { token, userUUID, sessionID, beaconSizeLimit } = r;
|
|
296
303
|
if (typeof token !== 'string' ||
|
|
@@ -302,9 +309,9 @@ export default class App {
|
|
|
302
309
|
this.localStorage.setItem(this.options.local_uuid_key, userUUID);
|
|
303
310
|
this.session.update({ sessionID }); // TODO: no no-explicit 'any'
|
|
304
311
|
const startWorkerMsg = {
|
|
305
|
-
type:
|
|
312
|
+
type: 'auth',
|
|
306
313
|
token,
|
|
307
|
-
beaconSizeLimit
|
|
314
|
+
beaconSizeLimit,
|
|
308
315
|
};
|
|
309
316
|
this.worker.postMessage(startWorkerMsg);
|
|
310
317
|
this.activityState = ActivityState.Active;
|
|
@@ -312,21 +319,21 @@ export default class App {
|
|
|
312
319
|
this.startCallbacks.forEach((cb) => cb(onStartInfo)); // TODO: start as early as possible (before receiving the token)
|
|
313
320
|
this.observer.observe();
|
|
314
321
|
this.ticker.start();
|
|
315
|
-
this.notify.log(
|
|
322
|
+
this.notify.log('OpenReplay tracking started.');
|
|
316
323
|
// get rid of onStart ?
|
|
317
324
|
if (typeof this.options.onStart === 'function') {
|
|
318
325
|
this.options.onStart(onStartInfo);
|
|
319
326
|
}
|
|
320
327
|
return SuccessfulStart(onStartInfo);
|
|
321
328
|
})
|
|
322
|
-
.catch(reason => {
|
|
329
|
+
.catch((reason) => {
|
|
323
330
|
this.sessionStorage.removeItem(this.options.session_token_key);
|
|
324
331
|
this.stop();
|
|
325
332
|
if (reason === CANCELED) {
|
|
326
333
|
return UnsuccessfulStart(CANCELED);
|
|
327
334
|
}
|
|
328
|
-
this.notify.log(
|
|
329
|
-
this._debug(
|
|
335
|
+
this.notify.log('OpenReplay was unable to start. ', reason);
|
|
336
|
+
this._debug('session_start', reason);
|
|
330
337
|
return UnsuccessfulStart(START_ERROR);
|
|
331
338
|
});
|
|
332
339
|
}
|
|
@@ -338,11 +345,11 @@ export default class App {
|
|
|
338
345
|
return new Promise((resolve) => {
|
|
339
346
|
const onVisibilityChange = () => {
|
|
340
347
|
if (!document.hidden) {
|
|
341
|
-
document.removeEventListener(
|
|
348
|
+
document.removeEventListener('visibilitychange', onVisibilityChange);
|
|
342
349
|
resolve(this._start(options));
|
|
343
350
|
}
|
|
344
351
|
};
|
|
345
|
-
document.addEventListener(
|
|
352
|
+
document.addEventListener('visibilitychange', onVisibilityChange);
|
|
346
353
|
});
|
|
347
354
|
}
|
|
348
355
|
}
|
|
@@ -357,9 +364,9 @@ export default class App {
|
|
|
357
364
|
if (calledFromAPI) {
|
|
358
365
|
this.session.reset();
|
|
359
366
|
}
|
|
360
|
-
this.notify.log(
|
|
367
|
+
this.notify.log('OpenReplay tracking stopped.');
|
|
361
368
|
if (this.worker && !restarting) {
|
|
362
|
-
this.worker.postMessage(
|
|
369
|
+
this.worker.postMessage('stop');
|
|
363
370
|
}
|
|
364
371
|
}
|
|
365
372
|
finally {
|
package/lib/app/logger.js
CHANGED
|
@@ -10,9 +10,12 @@ function IsCustomLevel(l) {
|
|
|
10
10
|
}
|
|
11
11
|
export default class Logger {
|
|
12
12
|
constructor(options = LogLevel.Silent) {
|
|
13
|
-
this.options =
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
this.options =
|
|
14
|
+
options === true
|
|
15
|
+
? { level: LogLevel.Verbose }
|
|
16
|
+
: typeof options === 'number'
|
|
17
|
+
? { level: options }
|
|
18
|
+
: options;
|
|
16
19
|
}
|
|
17
20
|
log(...args) {
|
|
18
21
|
if (IsCustomLevel(this.options.level)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Observer from
|
|
2
|
-
import { CreateIFrameDocument } from
|
|
1
|
+
import Observer from './observer.js';
|
|
2
|
+
import { CreateIFrameDocument } from '../../common/messages.js';
|
|
3
3
|
export default class IFrameObserver extends Observer {
|
|
4
4
|
observe(iframe) {
|
|
5
5
|
const doc = iframe.contentDocument;
|
|
@@ -10,7 +10,7 @@ export default class IFrameObserver extends Observer {
|
|
|
10
10
|
// Have to observe document, because the inner <html> might be changed
|
|
11
11
|
this.observeRoot(doc, (docID) => {
|
|
12
12
|
if (docID === undefined) {
|
|
13
|
-
console.log(
|
|
13
|
+
console.log('OpenReplay: Iframe document not bound');
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
this.app.send(CreateIFrameDocument(hostID, docID));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RemoveNodeAttribute, SetNodeAttribute, SetNodeAttributeURLBased, SetCSSDataURLBased, SetNodeData, CreateTextNode, CreateElementNode, MoveNode, RemoveNode, } from
|
|
2
|
-
import { isRootNode, isTextNode, isElementNode, isSVGElement, hasTag
|
|
1
|
+
import { RemoveNodeAttribute, SetNodeAttribute, SetNodeAttributeURLBased, SetCSSDataURLBased, SetNodeData, CreateTextNode, CreateElementNode, MoveNode, RemoveNode, } from '../../common/messages.js';
|
|
2
|
+
import { isRootNode, isTextNode, isElementNode, isSVGElement, hasTag } from '../guards.js';
|
|
3
3
|
function isIgnored(node) {
|
|
4
4
|
if (isTextNode(node)) {
|
|
5
5
|
return false;
|
|
@@ -11,13 +11,9 @@ function isIgnored(node) {
|
|
|
11
11
|
if (tag === 'LINK') {
|
|
12
12
|
const rel = node.getAttribute('rel');
|
|
13
13
|
const as = node.getAttribute('as');
|
|
14
|
-
return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as ===
|
|
14
|
+
return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === 'style' || as === 'font');
|
|
15
15
|
}
|
|
16
|
-
return (tag === 'SCRIPT' ||
|
|
17
|
-
tag === 'NOSCRIPT' ||
|
|
18
|
-
tag === 'META' ||
|
|
19
|
-
tag === 'TITLE' ||
|
|
20
|
-
tag === 'BASE');
|
|
16
|
+
return (tag === 'SCRIPT' || tag === 'NOSCRIPT' || tag === 'META' || tag === 'TITLE' || tag === 'BASE');
|
|
21
17
|
}
|
|
22
18
|
function isObservable(node) {
|
|
23
19
|
if (isRootNode(node)) {
|
|
@@ -52,7 +48,8 @@ export default class Observer {
|
|
|
52
48
|
this.attributesMap = new Map();
|
|
53
49
|
this.textSet = new Set();
|
|
54
50
|
this.observer = new MutationObserver(this.app.safe((mutations) => {
|
|
55
|
-
for (const mutation of mutations) {
|
|
51
|
+
for (const mutation of mutations) {
|
|
52
|
+
// mutations order is sequential
|
|
56
53
|
const target = mutation.target;
|
|
57
54
|
const type = mutation.type;
|
|
58
55
|
if (!isObservable(target)) {
|
|
@@ -81,7 +78,7 @@ export default class Observer {
|
|
|
81
78
|
}
|
|
82
79
|
let attr = this.attributesMap.get(id);
|
|
83
80
|
if (attr === undefined) {
|
|
84
|
-
this.attributesMap.set(id, attr = new Set());
|
|
81
|
+
this.attributesMap.set(id, (attr = new Set()));
|
|
85
82
|
}
|
|
86
83
|
attr.add(name);
|
|
87
84
|
continue;
|
|
@@ -129,7 +126,7 @@ export default class Observer {
|
|
|
129
126
|
return;
|
|
130
127
|
}
|
|
131
128
|
if (name === 'value' &&
|
|
132
|
-
hasTag(node,
|
|
129
|
+
hasTag(node, 'INPUT') &&
|
|
133
130
|
node.type !== 'button' &&
|
|
134
131
|
node.type !== 'reset' &&
|
|
135
132
|
node.type !== 'submit') {
|
|
@@ -139,7 +136,7 @@ export default class Observer {
|
|
|
139
136
|
this.app.send(new RemoveNodeAttribute(id, name));
|
|
140
137
|
return;
|
|
141
138
|
}
|
|
142
|
-
if (name === 'style' || name === 'href' && hasTag(node,
|
|
139
|
+
if (name === 'style' || (name === 'href' && hasTag(node, 'LINK'))) {
|
|
143
140
|
this.app.send(new SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
|
|
144
141
|
return;
|
|
145
142
|
}
|
|
@@ -149,7 +146,7 @@ export default class Observer {
|
|
|
149
146
|
this.app.send(new SetNodeAttribute(id, name, value));
|
|
150
147
|
}
|
|
151
148
|
sendNodeData(id, parentElement, data) {
|
|
152
|
-
if (hasTag(parentElement,
|
|
149
|
+
if (hasTag(parentElement, 'STYLE') || hasTag(parentElement, 'style')) {
|
|
153
150
|
this.app.send(new SetCSSDataURLBased(id, data, this.app.getBaseHref()));
|
|
154
151
|
return;
|
|
155
152
|
}
|
|
@@ -161,7 +158,8 @@ export default class Observer {
|
|
|
161
158
|
if (isNew) {
|
|
162
159
|
this.recents.set(id, RecentsType.New);
|
|
163
160
|
}
|
|
164
|
-
else if (this.recents.get(id) !== RecentsType.New) {
|
|
161
|
+
else if (this.recents.get(id) !== RecentsType.New) {
|
|
162
|
+
// can we do just `else` here?
|
|
165
163
|
this.recents.set(id, RecentsType.Removed);
|
|
166
164
|
}
|
|
167
165
|
}
|
|
@@ -175,8 +173,7 @@ export default class Observer {
|
|
|
175
173
|
}
|
|
176
174
|
this.bindNode(node);
|
|
177
175
|
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
|
|
178
|
-
acceptNode: (node) => isIgnored(node)
|
|
179
|
-
|| (this.app.nodes.getID(node) !== undefined && !isChildUnbinding)
|
|
176
|
+
acceptNode: (node) => isIgnored(node) || (this.app.nodes.getID(node) !== undefined && !isChildUnbinding)
|
|
180
177
|
? NodeFilter.FILTER_REJECT
|
|
181
178
|
: NodeFilter.FILTER_ACCEPT,
|
|
182
179
|
},
|
|
@@ -207,7 +204,7 @@ export default class Observer {
|
|
|
207
204
|
// Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
|
|
208
205
|
// TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
|
|
209
206
|
// TODO: Clean the logic (though now it workd fine)
|
|
210
|
-
if (!hasTag(node,
|
|
207
|
+
if (!hasTag(node, 'HTML') || !this.isTopContext) {
|
|
211
208
|
if (parent === null) {
|
|
212
209
|
// Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
|
|
213
210
|
// That shouldn't affect the visual rendering ( should it? )
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Observer from
|
|
2
|
-
import { CreateIFrameDocument } from
|
|
1
|
+
import Observer from './observer.js';
|
|
2
|
+
import { CreateIFrameDocument } from '../../common/messages.js';
|
|
3
3
|
export default class ShadowRootObserver extends Observer {
|
|
4
4
|
observe(el) {
|
|
5
5
|
const shRoot = el.shadowRoot;
|
|
@@ -9,7 +9,7 @@ export default class ShadowRootObserver extends Observer {
|
|
|
9
9
|
} // log
|
|
10
10
|
this.observeRoot(shRoot, (rootID) => {
|
|
11
11
|
if (rootID === undefined) {
|
|
12
|
-
console.log(
|
|
12
|
+
console.log('OpenReplay: Shadow Root was not bound');
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
15
|
this.app.send(CreateIFrameDocument(hostID, rootID));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import Observer from
|
|
2
|
-
import { isElementNode, hasTag
|
|
3
|
-
import IFrameObserver from
|
|
4
|
-
import ShadowRootObserver from
|
|
5
|
-
import { CreateDocument } from
|
|
1
|
+
import Observer from './observer.js';
|
|
2
|
+
import { isElementNode, hasTag } from '../guards.js';
|
|
3
|
+
import IFrameObserver from './iframe_observer.js';
|
|
4
|
+
import ShadowRootObserver from './shadow_root_observer.js';
|
|
5
|
+
import { CreateDocument } from '../../common/messages.js';
|
|
6
6
|
import { IN_BROWSER, hasOpenreplayAttribute } from '../../utils.js';
|
|
7
7
|
const attachShadowNativeFn = IN_BROWSER ? Element.prototype.attachShadow : () => new ShadowRoot();
|
|
8
8
|
export default class TopObserver extends Observer {
|
|
@@ -11,18 +11,18 @@ export default class TopObserver extends Observer {
|
|
|
11
11
|
this.iframeObservers = [];
|
|
12
12
|
this.shadowRootObservers = [];
|
|
13
13
|
this.options = Object.assign({
|
|
14
|
-
captureIFrames: true
|
|
14
|
+
captureIFrames: true,
|
|
15
15
|
}, options);
|
|
16
16
|
// IFrames
|
|
17
|
-
this.app.nodes.attachNodeCallback(node => {
|
|
18
|
-
if (hasTag(node,
|
|
19
|
-
((this.options.captureIFrames && !hasOpenreplayAttribute(node,
|
|
20
|
-
|
|
17
|
+
this.app.nodes.attachNodeCallback((node) => {
|
|
18
|
+
if (hasTag(node, 'IFRAME') &&
|
|
19
|
+
((this.options.captureIFrames && !hasOpenreplayAttribute(node, 'obscured')) ||
|
|
20
|
+
hasOpenreplayAttribute(node, 'capture'))) {
|
|
21
21
|
this.handleIframe(node);
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
// ShadowDOM
|
|
25
|
-
this.app.nodes.attachNodeCallback(node => {
|
|
25
|
+
this.app.nodes.attachNodeCallback((node) => {
|
|
26
26
|
if (isElementNode(node) && node.shadowRoot !== null) {
|
|
27
27
|
this.handleShadowRoot(node.shadowRoot);
|
|
28
28
|
}
|
|
@@ -46,7 +46,7 @@ export default class TopObserver extends Observer {
|
|
|
46
46
|
this.iframeObservers.push(observer);
|
|
47
47
|
observer.observe(iframe);
|
|
48
48
|
});
|
|
49
|
-
iframe.addEventListener(
|
|
49
|
+
iframe.addEventListener('load', handle); // why app.attachEventListener not working?
|
|
50
50
|
handle();
|
|
51
51
|
}
|
|
52
52
|
handleShadowRoot(shRoot) {
|
|
@@ -58,14 +58,15 @@ export default class TopObserver extends Observer {
|
|
|
58
58
|
// Protection from several subsequent calls?
|
|
59
59
|
const observer = this;
|
|
60
60
|
Element.prototype.attachShadow = function () {
|
|
61
|
+
// eslint-disable-next-line
|
|
61
62
|
const shadow = attachShadowNativeFn.apply(this, arguments);
|
|
62
63
|
observer.handleShadowRoot(shadow);
|
|
63
64
|
return shadow;
|
|
64
65
|
};
|
|
65
66
|
// Can observe documentElement (<html>) here, because it is not supposed to be changing.
|
|
66
67
|
// However, it is possible in some exotic cases and may cause an ignorance of the newly created <html>
|
|
67
|
-
// In this case context.document have to be observed, but this will cause
|
|
68
|
-
// the change in the re-player behaviour caused by CreateDocument message:
|
|
68
|
+
// In this case context.document have to be observed, but this will cause
|
|
69
|
+
// the change in the re-player behaviour caused by CreateDocument message:
|
|
69
70
|
// the 0-node ("fRoot") will become #document rather than documentElement as it is now.
|
|
70
71
|
// Alternatively - observe(#document) then bindNode(documentElement)
|
|
71
72
|
this.observeRoot(window.document, () => {
|
|
@@ -74,9 +75,9 @@ export default class TopObserver extends Observer {
|
|
|
74
75
|
}
|
|
75
76
|
disconnect() {
|
|
76
77
|
Element.prototype.attachShadow = attachShadowNativeFn;
|
|
77
|
-
this.iframeObservers.forEach(o => o.disconnect());
|
|
78
|
+
this.iframeObservers.forEach((o) => o.disconnect());
|
|
78
79
|
this.iframeObservers = [];
|
|
79
|
-
this.shadowRootObservers.forEach(o => o.disconnect());
|
|
80
|
+
this.shadowRootObservers.forEach((o) => o.disconnect());
|
|
80
81
|
this.shadowRootObservers = [];
|
|
81
82
|
super.disconnect();
|
|
82
83
|
}
|
package/lib/app/sanitizer.d.ts
CHANGED