@openreplay/tracker 3.6.1 → 3.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/cjs/app/guards.d.ts +1 -2
- package/cjs/app/guards.js +3 -6
- package/cjs/app/index.d.ts +23 -28
- package/cjs/app/index.js +86 -107
- package/cjs/app/logger.js +3 -6
- package/cjs/app/nodes.d.ts +1 -1
- package/cjs/app/nodes.js +0 -2
- package/cjs/app/observer/iframe_observer.d.ts +1 -1
- package/cjs/app/observer/iframe_observer.js +3 -3
- package/cjs/app/observer/observer.d.ts +3 -2
- package/cjs/app/observer/observer.js +52 -50
- package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
- package/cjs/app/observer/shadow_root_observer.js +3 -3
- package/cjs/app/observer/top_observer.d.ts +2 -13
- package/cjs/app/observer/top_observer.js +23 -58
- package/cjs/app/sanitizer.d.ts +1 -1
- package/cjs/app/sanitizer.js +5 -5
- package/cjs/app/session.d.ts +2 -20
- package/cjs/app/session.js +6 -65
- package/cjs/app/ticker.d.ts +1 -1
- package/cjs/common/messages.d.ts +444 -0
- package/cjs/common/messages.js +794 -0
- package/cjs/common/types.d.ts +9 -0
- package/cjs/common/{interaction.js → types.js} +0 -0
- package/cjs/common/{interaction.d.ts → webworker.d.ts} +5 -5
- package/cjs/common/{messages.gen.js → webworker.js} +0 -1
- package/cjs/index.d.ts +9 -10
- package/cjs/index.js +36 -47
- package/cjs/modules/connection.d.ts +1 -1
- package/cjs/modules/connection.js +2 -2
- package/cjs/modules/console.d.ts +1 -1
- package/cjs/modules/console.js +21 -7
- package/cjs/modules/cssrules.d.ts +1 -1
- package/cjs/modules/cssrules.js +14 -18
- package/cjs/modules/exception.d.ts +3 -3
- package/cjs/modules/exception.js +18 -23
- package/cjs/modules/img.d.ts +1 -1
- package/cjs/modules/img.js +26 -39
- package/cjs/modules/input.d.ts +1 -1
- package/cjs/modules/input.js +21 -21
- package/cjs/modules/longtasks.d.ts +2 -0
- package/cjs/modules/longtasks.js +26 -0
- package/cjs/modules/mouse.d.ts +1 -1
- package/cjs/modules/mouse.js +43 -50
- package/cjs/modules/performance.d.ts +1 -1
- package/cjs/modules/performance.js +2 -2
- package/cjs/modules/scroll.d.ts +1 -1
- package/cjs/modules/scroll.js +7 -16
- package/cjs/modules/timing.d.ts +1 -1
- package/cjs/modules/timing.js +26 -14
- package/cjs/modules/viewport.d.ts +1 -1
- package/cjs/modules/viewport.js +4 -4
- package/cjs/utils.js +7 -7
- package/cjs/vendors/finder/finder.js +48 -53
- package/lib/app/guards.d.ts +1 -2
- package/lib/app/guards.js +2 -4
- package/lib/app/index.d.ts +23 -28
- package/lib/app/index.js +94 -115
- package/lib/app/logger.js +3 -6
- package/lib/app/nodes.d.ts +1 -1
- package/lib/app/nodes.js +0 -2
- 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 +3 -2
- package/lib/app/observer/observer.js +53 -51
- 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 -13
- package/lib/app/observer/top_observer.js +27 -62
- package/lib/app/sanitizer.d.ts +1 -1
- package/lib/app/sanitizer.js +7 -7
- package/lib/app/session.d.ts +2 -20
- package/lib/app/session.js +6 -65
- package/lib/app/ticker.d.ts +1 -1
- package/lib/common/messages.d.ts +444 -0
- package/lib/common/messages.js +790 -0
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/common/types.d.ts +9 -0
- package/lib/common/{interaction.js → types.js} +0 -0
- package/lib/common/{interaction.d.ts → webworker.d.ts} +5 -5
- package/lib/common/webworker.js +1 -0
- package/lib/index.d.ts +9 -10
- package/lib/index.js +49 -60
- package/lib/modules/connection.d.ts +1 -1
- package/lib/modules/connection.js +2 -2
- package/lib/modules/console.d.ts +1 -1
- package/lib/modules/console.js +22 -8
- package/lib/modules/cssrules.d.ts +1 -1
- package/lib/modules/cssrules.js +15 -19
- package/lib/modules/exception.d.ts +3 -3
- package/lib/modules/exception.js +18 -23
- package/lib/modules/img.d.ts +1 -1
- package/lib/modules/img.js +28 -41
- package/lib/modules/input.d.ts +1 -1
- package/lib/modules/input.js +23 -23
- package/lib/modules/longtasks.d.ts +2 -0
- package/lib/modules/longtasks.js +23 -0
- package/lib/modules/mouse.d.ts +1 -1
- package/lib/modules/mouse.js +46 -53
- package/lib/modules/performance.d.ts +1 -1
- package/lib/modules/performance.js +3 -3
- package/lib/modules/scroll.d.ts +1 -1
- package/lib/modules/scroll.js +8 -17
- package/lib/modules/timing.d.ts +1 -1
- package/lib/modules/timing.js +28 -16
- package/lib/modules/viewport.d.ts +1 -1
- package/lib/modules/viewport.js +4 -4
- package/lib/utils.js +7 -7
- package/lib/vendors/finder/finder.js +48 -53
- package/package.json +10 -27
- package/.eslintignore +0 -8
- package/.prettierignore +0 -1
- package/cjs/app/messages.d.ts +0 -52
- package/cjs/app/messages.gen.d.ts +0 -57
- package/cjs/app/messages.gen.js +0 -493
- package/cjs/app/messages.js +0 -234
- package/cjs/common/messages.gen.d.ts +0 -382
- package/cjs/modules/adoptedStyleSheets.d.ts +0 -2
- package/cjs/modules/adoptedStyleSheets.js +0 -127
- package/lib/app/messages.d.ts +0 -52
- package/lib/app/messages.gen.d.ts +0 -57
- package/lib/app/messages.gen.js +0 -434
- package/lib/app/messages.js +0 -181
- package/lib/common/messages.gen.d.ts +0 -382
- package/lib/common/messages.gen.js +0 -2
- package/lib/modules/adoptedStyleSheets.d.ts +0 -2
- package/lib/modules/adoptedStyleSheets.js +0 -124
package/lib/app/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Timestamp, Metadata, UserID } from
|
|
2
|
-
import { timestamp
|
|
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;
|
|
@@ -29,7 +29,7 @@ export default class App {
|
|
|
29
29
|
this.stopCallbacks = [];
|
|
30
30
|
this.commitCallbacks = [];
|
|
31
31
|
this.activityState = ActivityState.NotActive;
|
|
32
|
-
this.version = '3.6.
|
|
32
|
+
this.version = '3.6.2'; // TODO: version compatability check inside each plugin.
|
|
33
33
|
this.projectKey = projectKey;
|
|
34
34
|
this.options = Object.assign({
|
|
35
35
|
revID: '',
|
|
@@ -43,8 +43,8 @@ export default class App {
|
|
|
43
43
|
verbose: false,
|
|
44
44
|
__is_snippet: false,
|
|
45
45
|
__debug_report_edp: null,
|
|
46
|
-
localStorage: window
|
|
47
|
-
sessionStorage: window
|
|
46
|
+
localStorage: window.localStorage,
|
|
47
|
+
sessionStorage: window.sessionStorage,
|
|
48
48
|
}, options);
|
|
49
49
|
this.revID = this.options.revID;
|
|
50
50
|
this.sanitizer = new Sanitizer(this, options);
|
|
@@ -54,33 +54,32 @@ export default class App {
|
|
|
54
54
|
this.ticker.attach(() => this.commit());
|
|
55
55
|
this.debug = new Logger(this.options.__debug__);
|
|
56
56
|
this.notify = new Logger(this.options.verbose ? LogLevel.Warnings : LogLevel.Silent);
|
|
57
|
-
this.
|
|
58
|
-
this.sessionStorage = this.options.sessionStorage || window.sessionStorage;
|
|
59
|
-
this.session = new Session(this, this.options);
|
|
57
|
+
this.session = new Session();
|
|
60
58
|
this.session.attachUpdateCallback(({ userID, metadata }) => {
|
|
61
|
-
if (userID != null) {
|
|
62
|
-
|
|
63
|
-
this.send(UserID(userID));
|
|
59
|
+
if (userID != null) { // TODO: nullable userID
|
|
60
|
+
this.send(new UserID(userID));
|
|
64
61
|
}
|
|
65
62
|
if (metadata != null) {
|
|
66
|
-
Object.entries(metadata).forEach(([key, value]) => this.send(Metadata(key, value)));
|
|
63
|
+
Object.entries(metadata).forEach(([key, value]) => this.send(new Metadata(key, value)));
|
|
67
64
|
}
|
|
68
65
|
});
|
|
69
|
-
|
|
66
|
+
this.localStorage = this.options.localStorage;
|
|
67
|
+
this.sessionStorage = this.options.sessionStorage;
|
|
70
68
|
if (sessionToken != null) {
|
|
71
|
-
this.
|
|
69
|
+
this.sessionStorage.setItem(this.options.session_token_key, sessionToken);
|
|
72
70
|
}
|
|
73
71
|
try {
|
|
74
|
-
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";class t{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 i="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 s extends class{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}getCurrentOffset(){return this.offset}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,i){this.data.set(t,i)}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=i.encode(t),e=s.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(s,this.offset),this.offset+=e,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}{encode(t){switch(t[0]){case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 82:return this.uint(t[1])&&this.uint(t[2]);case 0:return this.uint(t[1]);case 4:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:return this.uint(t[1])&&this.uint(t[2]);case 6:return this.int(t[1])&&this.int(t[2]);case 7:return!0;case 8:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.string(t[4])&&this.boolean(t[5]);case 9:case 10:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 11:return this.uint(t[1]);case 12:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:return this.uint(t[1])&&this.string(t[2]);case 16:return this.uint(t[1])&&this.int(t[2])&&this.int(t[3]);case 17:return this.uint(t[1])&&this.string(t[2]);case 18:return this.uint(t[1])&&this.string(t[2])&&this.int(t[3]);case 19:return this.uint(t[1])&&this.boolean(t[2]);case 20:return this.uint(t[1])&&this.uint(t[2]);case 22:return this.string(t[1])&&this.string(t[2]);case 23:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 24:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 25:return this.string(t[1])&&this.string(t[2])&&this.string(t[3]);case 27:return this.string(t[1])&&this.string(t[2]);case 28:case 29:return this.string(t[1]);case 30:return this.string(t[1])&&this.string(t[2]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);case 38:return this.uint(t[1])&&this.uint(t[2]);case 39:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7]);case 40:return this.string(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 41:return this.string(t[1])&&this.string(t[2]);case 42:return this.string(t[1]);case 44:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 45:case 46:return this.string(t[1])&&this.string(t[2]);case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 48:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 49:return this.int(t[1])&&this.int(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 53:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8]);case 54:return this.uint(t[1])&&this.string(t[2]);case 55:return this.boolean(t[1]);case 59:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6])&&this.string(t[7]);case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 61:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 63:case 64:return this.string(t[1])&&this.string(t[2]);case 67:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 70:return this.uint(t[1])&&this.uint(t[2]);case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 75:case 76:case 77:return this.uint(t[1])&&this.uint(t[2])}}}class e{constructor(t,i,e,n){this.pageNo=t,this.timestamp=i,this.url=e,this.onBatch=n,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new s(this.beaconSize),this.sizeBuffer=new Uint8Array(3),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}writeType(t){return this.encoder.uint(t[0])}writeFields(t){return this.encoder.encode(t)}writeSizeAt(t,i){for(let i=0;i<3;i++)this.sizeBuffer[i]=t>>8*i;this.encoder.set(this.sizeBuffer,i)}prepare(){if(!this.encoder.isEmpty())return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url];this.writeType(t),this.writeFields(t),this.isEmpty=!0}writeWithSize(t){const i=this.encoder;if(!this.writeType(t)||!i.skip(3))return!1;const s=i.getCurrentOffset(),e=this.writeFields(t);if(e){const e=i.getCurrentOffset()-s;if(e>16777215)return console.warn("OpenReplay: max message size overflow."),!1;this.writeSizeAt(e,s-3),i.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if(0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),!this.writeWithSize(t))for(this.finaliseBatch();!this.writeWithSize(t);){if(this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder.reset(),void this.prepare();this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.encoder=new s(this.beaconSize),this.prepare()}}finaliseBatch(){this.isEmpty||(this.onBatch(this.encoder.flush()),this.prepare())}clean(){this.encoder.reset()}}var n;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(n||(n={}));let r=null,h=null;function u(){h&&h.finaliseBatch()}function a(){n.Stopping,null!==c&&(clearInterval(c),c=null),h&&(h.clean(),h=null),n.NotActive}n.NotActive;let o,c=null;self.onmessage=({data:i})=>{if(null!=i){if("stop"===i)return u(),void a();if(Array.isArray(i)){if(!h)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const t=h;i.forEach(i=>{55===i[0]&&(i[1]?o=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(o)),t.writeMessage(i)})}else{if("start"===i.type)return n.Starting,r=new t(i.ingestPoint,()=>{self.postMessage("restart")},()=>{r&&(r.clean(),r=null),a(),self.postMessage("failed")},i.connAttemptCount,i.connAttemptGap),h=new e(i.pageNo,i.timestamp,i.url,t=>r&&r.push(t)),null===c&&(c=setInterval(u,1e4)),n.Active;if("auth"===i.type){if(!r)throw new Error("WebWorker: sender not initialised. Received auth.");if(!h)throw new Error("WebWorker: writer not initialised. Received auth.");return r.authorise(i.token),void(i.beaconSizeLimit&&h.setBeaconSizeLimit(i.beaconSizeLimit))}}}else u()};'], { type: 'text/javascript' })));
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function i(...i){return new t(...i)}return i.prototype=t.prototype,i}const i=new Map;const s=t(class{constructor(t,i,s){this.pageNo=t,this.firstIndex=i,this.timestamp=s,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});i.set(80,s);const e=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});i.set(0,e);const n=t(class{constructor(t,i,s){this.url=t,this.referrer=i,this.navigationStart=s,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});i.set(4,n);const r=t(class{constructor(t,i){this.width=t,this.height=i,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});i.set(5,r);const h=t(class{constructor(t,i){this.x=t,this.y=i,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});i.set(6,h);const o=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});i.set(7,o);const c=t(class{constructor(t,i,s,e,n){this.id=t,this.parentID=i,this.index=s,this.tag=e,this.svg=n,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});i.set(8,c);const a=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(9,a);const u=t(class{constructor(t,i,s){this.id=t,this.parentID=i,this.index=s,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});i.set(10,u);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});i.set(11,d);const l=t(class{constructor(t,i,s){this.id=t,this.name=i,this.value=s,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});i.set(12,l);const p=t(class{constructor(t,i){this.id=t,this.name=i,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});i.set(13,p);const g=t(class{constructor(t,i){this.id=t,this.data=i,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});i.set(14,g);const m=t(class{constructor(t,i,s){this.id=t,this.x=i,this.y=s,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});i.set(16,m);const f=t(class{constructor(t,i){this.id=t,this.label=i,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});i.set(17,f);const y=t(class{constructor(t,i,s){this.id=t,this.value=i,this.mask=s,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});i.set(18,y);const _=t(class{constructor(t,i){this.id=t,this.checked=i,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});i.set(19,_);const v=t(class{constructor(t,i){this.x=t,this.y=i,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});i.set(20,v);const S=t(class{constructor(t,i){this.level=t,this.value=i,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});i.set(22,S);const b=t(class{constructor(t,i,s,e,n,r,h,o,c){this.requestStart=t,this.responseStart=i,this.responseEnd=s,this.domContentLoadedEventStart=e,this.domContentLoadedEventEnd=n,this.loadEventStart=r,this.loadEventEnd=h,this.firstPaint=o,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});i.set(23,b);const w=t(class{constructor(t,i,s){this.speedIndex=t,this.visuallyComplete=i,this.timeToInteractive=s,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});i.set(24,w);const E=t(class{constructor(t,i,s){this.name=t,this.message=i,this.payload=s,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});i.set(25,E);const x=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});i.set(27,x);const T=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});i.set(28,T);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});i.set(29,z);const k=t(class{constructor(t,i){this.key=t,this.value=i,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});i.set(30,k);const A=t(class{constructor(t,i,s){this.id=t,this.rule=i,this.index=s,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});i.set(37,A);const I=t(class{constructor(t,i){this.id=t,this.index=i,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});i.set(38,I);const L=t(class{constructor(t,i,s,e,n,r,h){this.method=t,this.url=i,this.request=s,this.response=e,this.status=n,this.timestamp=r,this.duration=h,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});i.set(39,L);const C=t(class{constructor(t,i,s,e){this.name=t,this.duration=i,this.args=s,this.result=e,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});i.set(40,C);const M=t(class{constructor(t,i){this.key=t,this.value=i,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});i.set(41,M);const N=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});i.set(42,N);const B=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(44,B);const U=t(class{constructor(t,i){this.mutation=t,this.state=i,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});i.set(45,U);const R=t(class{constructor(t,i){this.type=t,this.payload=i,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});i.set(46,R);const O=t(class{constructor(t,i,s){this.action=t,this.state=i,this.duration=s,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});i.set(47,O);const P=t(class{constructor(t,i,s,e){this.operationKind=t,this.operationName=i,this.variables=s,this.response=e,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});i.set(48,P);const q=t(class{constructor(t,i,s,e){this.frames=t,this.ticks=i,this.totalJSHeapSize=s,this.usedJSHeapSize=e,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});i.set(49,q);const D=t(class{constructor(t,i,s,e,n,r,h,o){this.timestamp=t,this.duration=i,this.ttfb=s,this.headerSize=e,this.encodedBodySize=n,this.decodedBodySize=r,this.url=h,this.initiator=o,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});i.set(53,D);const W=t(class{constructor(t,i){this.downlink=t,this.type=i,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});i.set(54,W);const H=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});i.set(55,H);const J=t(class{constructor(t,i,s,e,n,r,h){this.timestamp=t,this.duration=i,this.context=s,this.containerType=e,this.containerSrc=n,this.containerId=r,this.containerName=h,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});i.set(59,J);const F=t(class{constructor(t,i,s,e){this.id=t,this.name=i,this.value=s,this.baseURL=e,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});i.set(60,F);const X=t(class{constructor(t,i,s){this.id=t,this.data=i,this.baseURL=s,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});i.set(61,X);const G=t(class{constructor(t,i){this.type=t,this.value=i,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});i.set(63,G);const K=t(class{constructor(t,i){this.name=t,this.payload=i,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});i.set(64,K);const j=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});i.set(65,j);const Q=t(class{constructor(t,i,s,e){this.id=t,this.rule=i,this.index=s,this.baseURL=e,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});i.set(67,Q);const V=t(class{constructor(t,i,s,e){this.id=t,this.hesitationTime=i,this.label=s,this.selector=e,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});i.set(69,V);const Y=t(class{constructor(t,i){this.frameID=t,this.id=i,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});i.set(70,Y);class Z{constructor(t,i,s,e=10,n=1e3){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i"}authorise(t){this.token=t}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure():(this.attemptsCount++,setTimeout(()=>this.sendBatch(t),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t){this.busy=!0,fetch(this.ingestURL,{body:t,method:"POST",headers:{Authorization:"Bearer "+this.token},keepalive:t.length<65536}).then(i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();if(i.status>=400)return void this.retry(t);this.attemptsCount=0;const s=this.queue.shift();s?this.sendBatch(s):this.busy=!1}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0}}const tt="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(var n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(!((r=t.charCodeAt(h))>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(h+=1,(n=1024*(n-55296)+r-56320+65536)>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class it{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=tt.encode(t),s=i.byteLength;return!(!this.uint(s)||this.offset+s>this.size)&&(this.data.set(i,this.offset),this.offset+=s,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class st{constructor(t,i,s){this.pageNo=t,this.timestamp=i,this.onBatch=s,this.nextIndex=0,this.beaconSize=2e5,this.writer=new it(this.beaconSize),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}prepare(){this.writer.isEmpty()&&new s(this.pageNo,this.nextIndex,this.timestamp).encode(this.writer)}write(t){const i=t.encode(this.writer);return i&&(this.isEmpty=!1,this.writer.checkpoint(),this.nextIndex++),i}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){for(t instanceof e&&(this.timestamp=t.timestamp);!this.write(t);){if(this.finaliseBatch(),this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message."),this.writer.reset(),this.prepare(),void(this.isEmpty=!0);this.beaconSize=Math.min(2*this.beaconSize,this.beaconSizeLimit),this.writer=new it(this.beaconSize),this.prepare(),this.isEmpty=!0}}finaliseBatch(){this.isEmpty||(this.onBatch(this.writer.flush()),this.prepare(),this.isEmpty=!0)}clean(){this.writer.reset()}}var et;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(et||(et={}));let nt=null,rt=null;function ht(){rt&&rt.finaliseBatch()}function ot(){et.Stopping,null!==at&&(clearInterval(at),at=null),rt&&(rt.clean(),rt=null),et.NotActive}et.NotActive;let ct,at=null;self.onmessage=({data:t})=>{if(null!=t){if("stop"===t)return ht(),void ot();if(Array.isArray(t)){if(!rt)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const s=rt;t.forEach(t=>{const e=new(i.get(t._id));Object.assign(e,t),e instanceof H&&(e.hidden?ct=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(ct)),s.writeMessage(e)})}else{if("start"===t.type)return et.Starting,nt=new Z(t.ingestPoint,()=>{self.postMessage("restart")},()=>{nt&&(nt.clean(),nt=null),ot(),self.postMessage("failed")},t.connAttemptCount,t.connAttemptGap),rt=new st(t.pageNo,t.timestamp,t=>nt&&nt.push(t)),null===at&&(at=setInterval(ht,1e4)),et.Active;if("auth"===t.type){if(!nt)throw new Error("WebWorker: sender not initialised. Received auth.");if(!rt)throw new Error("WebWorker: writer not initialised. Received auth.");return nt.authorise(t.token),void(t.beaconSizeLimit&&rt.setBeaconSizeLimit(t.beaconSizeLimit))}}}else ht()};
|
|
73
|
+
`], { type: 'text/javascript' })));
|
|
74
|
+
this.worker.onerror = e => {
|
|
75
|
+
this._debug("webworker_error", e);
|
|
77
76
|
};
|
|
78
77
|
this.worker.onmessage = ({ data }) => {
|
|
79
|
-
if (data ===
|
|
78
|
+
if (data === "failed") {
|
|
80
79
|
this.stop();
|
|
81
|
-
this._debug(
|
|
80
|
+
this._debug("worker_failed", {}); // add context (from worker)
|
|
82
81
|
}
|
|
83
|
-
else if (data ===
|
|
82
|
+
else if (data === "restart") {
|
|
84
83
|
this.stop();
|
|
85
84
|
this.start({ forceNew: true });
|
|
86
85
|
}
|
|
@@ -97,7 +96,7 @@ export default class App {
|
|
|
97
96
|
this.attachEventListener(document, 'visibilitychange', alertWorker, false);
|
|
98
97
|
}
|
|
99
98
|
catch (e) {
|
|
100
|
-
this._debug(
|
|
99
|
+
this._debug("worker_start", e);
|
|
101
100
|
}
|
|
102
101
|
}
|
|
103
102
|
_debug(context, e) {
|
|
@@ -107,20 +106,20 @@ export default class App {
|
|
|
107
106
|
headers: { 'Content-Type': 'application/json' },
|
|
108
107
|
body: JSON.stringify({
|
|
109
108
|
context,
|
|
110
|
-
error: `${e}
|
|
111
|
-
})
|
|
109
|
+
error: `${e}`
|
|
110
|
+
})
|
|
112
111
|
});
|
|
113
112
|
}
|
|
114
|
-
this.debug.error(
|
|
113
|
+
this.debug.error("OpenReplay error: ", context, e);
|
|
115
114
|
}
|
|
116
115
|
send(message, urgent = false) {
|
|
117
116
|
if (this.activityState === ActivityState.NotActive) {
|
|
118
117
|
return;
|
|
119
118
|
}
|
|
120
119
|
this.messages.push(message);
|
|
121
|
-
// TODO: commit on start if there were `urgent` sends;
|
|
120
|
+
// TODO: commit on start if there were `urgent` sends;
|
|
122
121
|
// Clearify where urgent can be used for;
|
|
123
|
-
// Clearify workflow for each type of message in case it was sent before start
|
|
122
|
+
// Clearify workflow for each type of message in case it was sent before start
|
|
124
123
|
// (like Fetch before start; maybe add an option "preCapture: boolean" or sth alike)
|
|
125
124
|
if (this.activityState === ActivityState.Active && urgent) {
|
|
126
125
|
this.commit();
|
|
@@ -128,9 +127,9 @@ export default class App {
|
|
|
128
127
|
}
|
|
129
128
|
commit() {
|
|
130
129
|
if (this.worker && this.messages.length) {
|
|
131
|
-
this.messages.unshift(Timestamp(
|
|
130
|
+
this.messages.unshift(new Timestamp(timestamp()));
|
|
132
131
|
this.worker.postMessage(this.messages);
|
|
133
|
-
this.commitCallbacks.forEach(
|
|
132
|
+
this.commitCallbacks.forEach(cb => cb(this.messages));
|
|
134
133
|
this.messages.length = 0;
|
|
135
134
|
}
|
|
136
135
|
}
|
|
@@ -141,8 +140,8 @@ export default class App {
|
|
|
141
140
|
fn.apply(this, args);
|
|
142
141
|
}
|
|
143
142
|
catch (e) {
|
|
144
|
-
app._debug(
|
|
145
|
-
// time:
|
|
143
|
+
app._debug("safe_fn_call", e);
|
|
144
|
+
// time: timestamp(),
|
|
146
145
|
// name: e.name,
|
|
147
146
|
// message: e.message,
|
|
148
147
|
// stack: e.stack
|
|
@@ -150,72 +149,54 @@ export default class App {
|
|
|
150
149
|
}; // TODO: correct typing
|
|
151
150
|
}
|
|
152
151
|
attachCommitCallback(cb) {
|
|
153
|
-
// TODO!: what if start callback added when activityState === Active ?
|
|
154
|
-
// For example - attachEventListener() called during dynamic <iframe> appearance
|
|
155
152
|
this.commitCallbacks.push(cb);
|
|
156
153
|
}
|
|
157
|
-
attachStartCallback(cb
|
|
158
|
-
if (useSafe) {
|
|
159
|
-
cb = this.safe(cb);
|
|
160
|
-
}
|
|
154
|
+
attachStartCallback(cb) {
|
|
161
155
|
this.startCallbacks.push(cb);
|
|
162
156
|
}
|
|
163
|
-
attachStopCallback(cb
|
|
164
|
-
if (useSafe) {
|
|
165
|
-
cb = this.safe(cb);
|
|
166
|
-
}
|
|
157
|
+
attachStopCallback(cb) {
|
|
167
158
|
this.stopCallbacks.push(cb);
|
|
168
159
|
}
|
|
169
160
|
attachEventListener(target, type, listener, useSafe = true, useCapture = true) {
|
|
170
161
|
if (useSafe) {
|
|
171
162
|
listener = this.safe(listener);
|
|
172
163
|
}
|
|
173
|
-
this.attachStartCallback(() => target.addEventListener(type, listener, useCapture)
|
|
174
|
-
this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture)
|
|
164
|
+
this.attachStartCallback(() => target.addEventListener(type, listener, useCapture));
|
|
165
|
+
this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture));
|
|
175
166
|
}
|
|
176
167
|
// TODO: full correct semantic
|
|
177
168
|
checkRequiredVersion(version) {
|
|
178
169
|
const reqVer = version.split(/[.-]/);
|
|
179
170
|
const ver = this.version.split(/[.-]/);
|
|
180
171
|
for (let i = 0; i < 3; i++) {
|
|
181
|
-
if (isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
if (Number(ver[i]) > Number(reqVer[i])) {
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
if (Number(ver[i]) < Number(reqVer[i])) {
|
|
172
|
+
if (Number(ver[i]) < Number(reqVer[i]) || isNaN(Number(ver[i])) || isNaN(Number(reqVer[i]))) {
|
|
188
173
|
return false;
|
|
189
174
|
}
|
|
190
175
|
}
|
|
191
176
|
return true;
|
|
192
177
|
}
|
|
193
|
-
|
|
178
|
+
getStartInfo() {
|
|
194
179
|
return {
|
|
195
180
|
userUUID: this.localStorage.getItem(this.options.local_uuid_key),
|
|
196
181
|
projectKey: this.projectKey,
|
|
197
182
|
revID: this.revID,
|
|
183
|
+
timestamp: timestamp(),
|
|
198
184
|
trackerVersion: this.version,
|
|
199
185
|
isSnippet: this.options.__is_snippet,
|
|
200
186
|
};
|
|
201
187
|
}
|
|
202
188
|
getSessionInfo() {
|
|
203
|
-
return Object.assign(Object.assign({}, this.session.getInfo()), this.
|
|
189
|
+
return Object.assign(Object.assign({}, this.session.getInfo()), this.getStartInfo());
|
|
204
190
|
}
|
|
205
191
|
getSessionToken() {
|
|
206
|
-
|
|
192
|
+
const token = this.sessionStorage.getItem(this.options.session_token_key);
|
|
193
|
+
if (token !== null) {
|
|
194
|
+
return token;
|
|
195
|
+
}
|
|
207
196
|
}
|
|
208
197
|
getSessionID() {
|
|
209
198
|
return this.session.getInfo().sessionID || undefined;
|
|
210
199
|
}
|
|
211
|
-
getSessionURL() {
|
|
212
|
-
const { projectID, sessionID } = this.session.getInfo();
|
|
213
|
-
if (!projectID || !sessionID) {
|
|
214
|
-
this.debug.error('OpenReplay error: Unable to build session URL');
|
|
215
|
-
return undefined;
|
|
216
|
-
}
|
|
217
|
-
return this.options.ingestPoint.replace(/ingest$/, `${projectID}/session/${sessionID}`);
|
|
218
|
-
}
|
|
219
200
|
getHost() {
|
|
220
201
|
return new URL(this.options.ingestPoint).hostname;
|
|
221
202
|
}
|
|
@@ -228,19 +209,18 @@ export default class App {
|
|
|
228
209
|
return this.options.resourceBaseHref;
|
|
229
210
|
}
|
|
230
211
|
else if (typeof this.options.resourceBaseHref === 'object') {
|
|
231
|
-
//
|
|
212
|
+
//switch between types
|
|
232
213
|
}
|
|
233
214
|
if (document.baseURI) {
|
|
234
215
|
return document.baseURI;
|
|
235
216
|
}
|
|
236
217
|
// IE only
|
|
237
|
-
return ((
|
|
238
|
-
location.origin + location.pathname);
|
|
218
|
+
return ((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName("base")[0]) === null || _b === void 0 ? void 0 : _b.getAttribute("href")) || location.origin + location.pathname;
|
|
239
219
|
}
|
|
240
220
|
resolveResourceURL(resourceURL) {
|
|
241
221
|
const base = new URL(this.getBaseHref());
|
|
242
|
-
base.pathname +=
|
|
243
|
-
base.pathname.replace(/\/+/g,
|
|
222
|
+
base.pathname += "/" + new URL(resourceURL).pathname;
|
|
223
|
+
base.pathname.replace(/\/+/g, "/");
|
|
244
224
|
return base.toString();
|
|
245
225
|
}
|
|
246
226
|
isServiceURL(url) {
|
|
@@ -259,98 +239,94 @@ export default class App {
|
|
|
259
239
|
}
|
|
260
240
|
_start(startOpts) {
|
|
261
241
|
if (!this.worker) {
|
|
262
|
-
return Promise.resolve(UnsuccessfulStart(
|
|
242
|
+
return Promise.resolve(UnsuccessfulStart("No worker found: perhaps, CSP is not set."));
|
|
263
243
|
}
|
|
264
244
|
if (this.activityState !== ActivityState.NotActive) {
|
|
265
|
-
return Promise.resolve(UnsuccessfulStart(
|
|
245
|
+
return Promise.resolve(UnsuccessfulStart("OpenReplay: trying to call `start()` on the instance that has been started already."));
|
|
266
246
|
}
|
|
267
247
|
this.activityState = ActivityState.Starting;
|
|
268
|
-
|
|
269
|
-
|
|
248
|
+
let pageNo = 0;
|
|
249
|
+
const pageNoStr = this.sessionStorage.getItem(this.options.session_pageno_key);
|
|
250
|
+
if (pageNoStr != null) {
|
|
251
|
+
pageNo = parseInt(pageNoStr);
|
|
252
|
+
pageNo++;
|
|
270
253
|
}
|
|
271
|
-
|
|
254
|
+
this.sessionStorage.setItem(this.options.session_pageno_key, pageNo.toString());
|
|
255
|
+
const startInfo = this.getStartInfo();
|
|
272
256
|
const startWorkerMsg = {
|
|
273
|
-
type:
|
|
274
|
-
pageNo
|
|
257
|
+
type: "start",
|
|
258
|
+
pageNo,
|
|
275
259
|
ingestPoint: this.options.ingestPoint,
|
|
276
|
-
timestamp,
|
|
277
|
-
url: document.URL,
|
|
260
|
+
timestamp: startInfo.timestamp,
|
|
278
261
|
connAttemptCount: this.options.connAttemptCount,
|
|
279
262
|
connAttemptGap: this.options.connAttemptGap,
|
|
280
263
|
};
|
|
281
264
|
this.worker.postMessage(startWorkerMsg);
|
|
282
265
|
this.session.update({
|
|
283
|
-
//
|
|
284
|
-
// "updating" with old metadata in order to trigger session's UpdateCallbacks.
|
|
266
|
+
// "updating" with old metadata in order to trigger session's UpdateCallbacks.
|
|
285
267
|
// (for the case of internal .start() calls, like on "restart" webworker signal or assistent connection in tracker-assist )
|
|
286
268
|
metadata: startOpts.metadata || this.session.getInfo().metadata,
|
|
287
269
|
userID: startOpts.userID,
|
|
288
270
|
});
|
|
289
271
|
const sReset = this.sessionStorage.getItem(this.options.session_reset_key);
|
|
290
272
|
this.sessionStorage.removeItem(this.options.session_reset_key);
|
|
291
|
-
return window
|
|
292
|
-
.fetch(this.options.ingestPoint + '/v1/web/start', {
|
|
273
|
+
return window.fetch(this.options.ingestPoint + '/v1/web/start', {
|
|
293
274
|
method: 'POST',
|
|
294
275
|
headers: {
|
|
295
276
|
'Content-Type': 'application/json',
|
|
296
277
|
},
|
|
297
|
-
body: JSON.stringify(Object.assign(Object.assign({},
|
|
278
|
+
body: JSON.stringify(Object.assign(Object.assign({}, startInfo), { userID: this.session.getInfo().userID, token: this.sessionStorage.getItem(this.options.session_token_key), deviceMemory,
|
|
298
279
|
jsHeapSizeLimit, reset: startOpts.forceNew || sReset !== null })),
|
|
299
280
|
})
|
|
300
|
-
.then(
|
|
281
|
+
.then(r => {
|
|
301
282
|
if (r.status === 200) {
|
|
302
283
|
return r.json();
|
|
303
284
|
}
|
|
304
285
|
else {
|
|
305
|
-
return r
|
|
306
|
-
.text()
|
|
307
|
-
.then((text) => text === CANCELED
|
|
286
|
+
return r.text().then(text => text === CANCELED
|
|
308
287
|
? Promise.reject(CANCELED)
|
|
309
288
|
: Promise.reject(`Server error: ${r.status}. ${text}`));
|
|
310
289
|
}
|
|
311
290
|
})
|
|
312
|
-
.then(
|
|
291
|
+
.then(r => {
|
|
313
292
|
if (!this.worker) {
|
|
314
|
-
return Promise.reject(
|
|
293
|
+
return Promise.reject("no worker found after start request (this might not happen)");
|
|
315
294
|
}
|
|
316
|
-
const { token, userUUID, sessionID,
|
|
317
|
-
} = r;
|
|
295
|
+
const { token, userUUID, sessionID, beaconSizeLimit } = r;
|
|
318
296
|
if (typeof token !== 'string' ||
|
|
319
297
|
typeof userUUID !== 'string' ||
|
|
320
|
-
//typeof startTimestamp !== 'number' ||
|
|
321
|
-
//typeof sessionID !== 'string' ||
|
|
322
298
|
(typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) {
|
|
323
299
|
return Promise.reject(`Incorrect server response: ${JSON.stringify(r)}`);
|
|
324
300
|
}
|
|
325
|
-
this.
|
|
301
|
+
this.sessionStorage.setItem(this.options.session_token_key, token);
|
|
326
302
|
this.localStorage.setItem(this.options.local_uuid_key, userUUID);
|
|
327
|
-
this.session.update({ sessionID
|
|
303
|
+
this.session.update({ sessionID }); // TODO: no no-explicit 'any'
|
|
328
304
|
const startWorkerMsg = {
|
|
329
|
-
type:
|
|
305
|
+
type: "auth",
|
|
330
306
|
token,
|
|
331
|
-
beaconSizeLimit
|
|
307
|
+
beaconSizeLimit
|
|
332
308
|
};
|
|
333
309
|
this.worker.postMessage(startWorkerMsg);
|
|
310
|
+
this.activityState = ActivityState.Active;
|
|
334
311
|
const onStartInfo = { sessionToken: token, userUUID, sessionID };
|
|
335
312
|
this.startCallbacks.forEach((cb) => cb(onStartInfo)); // TODO: start as early as possible (before receiving the token)
|
|
336
313
|
this.observer.observe();
|
|
337
314
|
this.ticker.start();
|
|
338
|
-
this.
|
|
339
|
-
this.notify.log('OpenReplay tracking started.');
|
|
315
|
+
this.notify.log("OpenReplay tracking started.");
|
|
340
316
|
// get rid of onStart ?
|
|
341
317
|
if (typeof this.options.onStart === 'function') {
|
|
342
318
|
this.options.onStart(onStartInfo);
|
|
343
319
|
}
|
|
344
320
|
return SuccessfulStart(onStartInfo);
|
|
345
321
|
})
|
|
346
|
-
.catch(
|
|
322
|
+
.catch(reason => {
|
|
323
|
+
this.sessionStorage.removeItem(this.options.session_token_key);
|
|
347
324
|
this.stop();
|
|
348
|
-
this.session.reset();
|
|
349
325
|
if (reason === CANCELED) {
|
|
350
326
|
return UnsuccessfulStart(CANCELED);
|
|
351
327
|
}
|
|
352
|
-
this.notify.log(
|
|
353
|
-
this._debug(
|
|
328
|
+
this.notify.log("OpenReplay was unable to start. ", reason);
|
|
329
|
+
this._debug("session_start", reason);
|
|
354
330
|
return UnsuccessfulStart(START_ERROR);
|
|
355
331
|
});
|
|
356
332
|
}
|
|
@@ -362,15 +338,15 @@ export default class App {
|
|
|
362
338
|
return new Promise((resolve) => {
|
|
363
339
|
const onVisibilityChange = () => {
|
|
364
340
|
if (!document.hidden) {
|
|
365
|
-
document.removeEventListener(
|
|
341
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
366
342
|
resolve(this._start(options));
|
|
367
343
|
}
|
|
368
344
|
};
|
|
369
|
-
document.addEventListener(
|
|
345
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
370
346
|
});
|
|
371
347
|
}
|
|
372
348
|
}
|
|
373
|
-
stop(
|
|
349
|
+
stop(calledFromAPI = false, restarting = false) {
|
|
374
350
|
if (this.activityState !== ActivityState.NotActive) {
|
|
375
351
|
try {
|
|
376
352
|
this.sanitizer.clear();
|
|
@@ -378,9 +354,12 @@ export default class App {
|
|
|
378
354
|
this.nodes.clear();
|
|
379
355
|
this.ticker.stop();
|
|
380
356
|
this.stopCallbacks.forEach((cb) => cb());
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
357
|
+
if (calledFromAPI) {
|
|
358
|
+
this.session.reset();
|
|
359
|
+
}
|
|
360
|
+
this.notify.log("OpenReplay tracking stopped.");
|
|
361
|
+
if (this.worker && !restarting) {
|
|
362
|
+
this.worker.postMessage("stop");
|
|
384
363
|
}
|
|
385
364
|
}
|
|
386
365
|
finally {
|
|
@@ -389,7 +368,7 @@ export default class App {
|
|
|
389
368
|
}
|
|
390
369
|
}
|
|
391
370
|
restart() {
|
|
392
|
-
this.stop(false);
|
|
371
|
+
this.stop(false, true);
|
|
393
372
|
this.start({ forceNew: false });
|
|
394
373
|
}
|
|
395
374
|
}
|
package/lib/app/logger.js
CHANGED
|
@@ -10,12 +10,9 @@ function IsCustomLevel(l) {
|
|
|
10
10
|
}
|
|
11
11
|
export default class Logger {
|
|
12
12
|
constructor(options = LogLevel.Silent) {
|
|
13
|
-
this.options =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
: typeof options === 'number'
|
|
17
|
-
? { level: options }
|
|
18
|
-
: options;
|
|
13
|
+
this.options = options === true
|
|
14
|
+
? { level: LogLevel.Verbose }
|
|
15
|
+
: typeof options === "number" ? { level: options } : options;
|
|
19
16
|
}
|
|
20
17
|
log(...args) {
|
|
21
18
|
if (IsCustomLevel(this.options.level)
|
package/lib/app/nodes.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export default class Nodes {
|
|
|
7
7
|
constructor(node_id: string);
|
|
8
8
|
attachNodeCallback(nodeCallback: NodeCallback): void;
|
|
9
9
|
attachElementListener(type: string, node: Element, elementListener: EventListener): void;
|
|
10
|
-
registerNode(node: Node): [
|
|
10
|
+
registerNode(node: Node): [id: number, isNew: boolean];
|
|
11
11
|
unregisterNode(node: Node): number | undefined;
|
|
12
12
|
cleanTree(): void;
|
|
13
13
|
callNodeCallbacks(node: Node, isStart: boolean): void;
|
package/lib/app/nodes.js
CHANGED
|
@@ -5,11 +5,9 @@ export default class Nodes {
|
|
|
5
5
|
this.nodeCallbacks = [];
|
|
6
6
|
this.elementListeners = new Map();
|
|
7
7
|
}
|
|
8
|
-
// Attached once per Tracker instance
|
|
9
8
|
attachNodeCallback(nodeCallback) {
|
|
10
9
|
this.nodeCallbacks.push(nodeCallback);
|
|
11
10
|
}
|
|
12
|
-
// TODO: what is the difference with app.attachEventListener. can we use only one of those?
|
|
13
11
|
attachElementListener(type, node, elementListener) {
|
|
14
12
|
const id = this.getID(node);
|
|
15
13
|
if (id === undefined) {
|
|
@@ -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,4 +1,4 @@
|
|
|
1
|
-
import App from
|
|
1
|
+
import App from "../index.js";
|
|
2
2
|
export default abstract class Observer {
|
|
3
3
|
protected readonly app: App;
|
|
4
4
|
protected readonly isTopContext: boolean;
|
|
@@ -13,8 +13,9 @@ export default abstract class Observer {
|
|
|
13
13
|
private sendNodeAttribute;
|
|
14
14
|
private sendNodeData;
|
|
15
15
|
private bindNode;
|
|
16
|
+
private unbindChildNode;
|
|
16
17
|
private bindTree;
|
|
17
|
-
private
|
|
18
|
+
private unbindNode;
|
|
18
19
|
private _commitNode;
|
|
19
20
|
private commitNode;
|
|
20
21
|
private commitNodes;
|