@openreplay/tracker 3.6.0-beta.0 → 3.6.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/LICENSE +1 -1
- package/cjs/app/index.d.ts +6 -3
- package/cjs/app/index.js +34 -14
- package/cjs/app/messages.gen.js +55 -56
- package/cjs/app/messages.js +50 -51
- package/cjs/app/nodes.d.ts +1 -1
- package/cjs/app/observer/top_observer.d.ts +3 -1
- package/cjs/app/observer/top_observer.js +8 -2
- package/cjs/app/session.d.ts +4 -2
- package/cjs/app/session.js +13 -3
- package/cjs/common/messages.gen.d.ts +214 -214
- package/cjs/common/messages.gen.js +0 -59
- package/cjs/index.d.ts +3 -2
- package/cjs/index.js +11 -5
- package/cjs/modules/adoptedStyleSheets.js +1 -1
- package/cjs/modules/exception.js +10 -10
- package/lib/app/index.d.ts +6 -3
- package/lib/app/index.js +34 -14
- package/lib/app/messages.gen.js +55 -56
- package/lib/app/messages.js +50 -51
- package/lib/app/nodes.d.ts +1 -1
- package/lib/app/observer/top_observer.d.ts +3 -1
- package/lib/app/observer/top_observer.js +8 -2
- package/lib/app/session.d.ts +4 -2
- package/lib/app/session.js +13 -3
- package/lib/common/messages.gen.d.ts +214 -214
- package/lib/common/messages.gen.js +1 -58
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.js +11 -5
- package/lib/modules/adoptedStyleSheets.js +1 -1
- package/lib/modules/exception.js +10 -10
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ const guards_js_1 = require("../app/guards.js");
|
|
|
5
5
|
function hasAdoptedSS(node) {
|
|
6
6
|
return ((0, guards_js_1.isRootNode)(node) &&
|
|
7
7
|
// @ts-ignore
|
|
8
|
-
|
|
8
|
+
!!node.adoptedStyleSheets);
|
|
9
9
|
}
|
|
10
10
|
function default_1(app) {
|
|
11
11
|
if (app === null) {
|
package/cjs/modules/exception.js
CHANGED
|
@@ -59,17 +59,17 @@ function default_1(app, opts) {
|
|
|
59
59
|
const options = Object.assign({
|
|
60
60
|
captureExceptions: true,
|
|
61
61
|
}, opts);
|
|
62
|
-
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
app.attachEventListener(context, 'unhandledrejection', handler);
|
|
71
|
-
app.attachEventListener(context, 'error', handler);
|
|
62
|
+
function patchContext(context) {
|
|
63
|
+
function handler(e) {
|
|
64
|
+
const msg = getExceptionMessageFromEvent(e, context);
|
|
65
|
+
if (msg != null) {
|
|
66
|
+
app.send(msg);
|
|
67
|
+
}
|
|
72
68
|
}
|
|
69
|
+
app.attachEventListener(context, 'unhandledrejection', handler);
|
|
70
|
+
app.attachEventListener(context, 'error', handler);
|
|
71
|
+
}
|
|
72
|
+
if (options.captureExceptions) {
|
|
73
73
|
app.observer.attachContextCallback(patchContext);
|
|
74
74
|
patchContext(window);
|
|
75
75
|
}
|
package/lib/app/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface StartOptions {
|
|
|
14
14
|
userID?: string;
|
|
15
15
|
metadata?: Record<string, string>;
|
|
16
16
|
forceNew?: boolean;
|
|
17
|
+
sessionHash?: string;
|
|
17
18
|
}
|
|
18
19
|
interface OnStartInfo {
|
|
19
20
|
sessionID: string;
|
|
@@ -72,14 +73,14 @@ export default class App {
|
|
|
72
73
|
private activityState;
|
|
73
74
|
private readonly version;
|
|
74
75
|
private readonly worker?;
|
|
75
|
-
constructor(projectKey: string,
|
|
76
|
+
constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>);
|
|
76
77
|
private _debug;
|
|
77
78
|
send(message: Message, urgent?: boolean): void;
|
|
78
79
|
private commit;
|
|
79
80
|
safe<T extends (...args: any[]) => void>(fn: T): T;
|
|
80
81
|
attachCommitCallback(cb: CommitCallback): void;
|
|
81
|
-
attachStartCallback(cb: StartCallback): void;
|
|
82
|
-
attachStopCallback(cb: () => any): void;
|
|
82
|
+
attachStartCallback(cb: StartCallback, useSafe?: boolean): void;
|
|
83
|
+
attachStopCallback(cb: () => any, useSafe?: boolean): void;
|
|
83
84
|
attachEventListener(target: EventTarget, type: string, listener: EventListener, useSafe?: boolean, useCapture?: boolean): void;
|
|
84
85
|
checkRequiredVersion(version: string): boolean;
|
|
85
86
|
private getTrackerInfo;
|
|
@@ -93,9 +94,11 @@ export default class App {
|
|
|
93
94
|
metadata: Record<string, string>;
|
|
94
95
|
userID: string | null;
|
|
95
96
|
timestamp: number;
|
|
97
|
+
projectID?: string | undefined;
|
|
96
98
|
};
|
|
97
99
|
getSessionToken(): string | undefined;
|
|
98
100
|
getSessionID(): string | undefined;
|
|
101
|
+
getSessionURL(): string | undefined;
|
|
99
102
|
getHost(): string;
|
|
100
103
|
getProjectKey(): string;
|
|
101
104
|
getBaseHref(): string;
|
package/lib/app/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var ActivityState;
|
|
|
20
20
|
// TODO: use backendHost only
|
|
21
21
|
export const DEFAULT_INGEST_POINT = 'https://api.openreplay.com/ingest';
|
|
22
22
|
export default class App {
|
|
23
|
-
constructor(projectKey,
|
|
23
|
+
constructor(projectKey, sessionToken, options) {
|
|
24
24
|
// if (options.onStart !== undefined) {
|
|
25
25
|
// deprecationWarn("'onStart' option", "tracker.start().then(/* handle session info */)")
|
|
26
26
|
// } ?? maybe onStart is good
|
|
@@ -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.
|
|
32
|
+
this.version = '3.6.0'; // 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: null,
|
|
47
|
-
sessionStorage: null,
|
|
46
|
+
localStorage: window === null || window === void 0 ? void 0 : window.localStorage,
|
|
47
|
+
sessionStorage: window === null || window === void 0 ? void 0 : window.sessionStorage,
|
|
48
48
|
}, options);
|
|
49
49
|
this.revID = this.options.revID;
|
|
50
50
|
this.sanitizer = new Sanitizer(this, options);
|
|
@@ -66,11 +66,12 @@ export default class App {
|
|
|
66
66
|
Object.entries(metadata).forEach(([key, value]) => this.send(Metadata(key, value)));
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
// @depricated (use sessionHash on start instead)
|
|
70
|
+
if (sessionToken != null) {
|
|
71
|
+
this.session.applySessionHash(sessionToken);
|
|
71
72
|
}
|
|
72
73
|
try {
|
|
73
|
-
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";var t;!function(t){t[t.BatchMetadata=81]="BatchMetadata",t[t.PartitionedMessage=82]="PartitionedMessage",t[t.Timestamp=0]="Timestamp",t[t.SetPageLocation=4]="SetPageLocation",t[t.SetViewportSize=5]="SetViewportSize",t[t.SetViewportScroll=6]="SetViewportScroll",t[t.CreateDocument=7]="CreateDocument",t[t.CreateElementNode=8]="CreateElementNode",t[t.CreateTextNode=9]="CreateTextNode",t[t.MoveNode=10]="MoveNode",t[t.RemoveNode=11]="RemoveNode",t[t.SetNodeAttribute=12]="SetNodeAttribute",t[t.RemoveNodeAttribute=13]="RemoveNodeAttribute",t[t.SetNodeData=14]="SetNodeData",t[t.SetNodeScroll=16]="SetNodeScroll",t[t.SetInputTarget=17]="SetInputTarget",t[t.SetInputValue=18]="SetInputValue",t[t.SetInputChecked=19]="SetInputChecked",t[t.MouseMove=20]="MouseMove",t[t.ConsoleLog=22]="ConsoleLog",t[t.PageLoadTiming=23]="PageLoadTiming",t[t.PageRenderTiming=24]="PageRenderTiming",t[t.JSException=25]="JSException",t[t.RawCustomEvent=27]="RawCustomEvent",t[t.UserID=28]="UserID",t[t.UserAnonymousID=29]="UserAnonymousID",t[t.Metadata=30]="Metadata",t[t.CSSInsertRule=37]="CSSInsertRule",t[t.CSSDeleteRule=38]="CSSDeleteRule",t[t.Fetch=39]="Fetch",t[t.Profiler=40]="Profiler",t[t.OTable=41]="OTable",t[t.StateAction=42]="StateAction",t[t.Redux=44]="Redux",t[t.Vuex=45]="Vuex",t[t.MobX=46]="MobX",t[t.NgRx=47]="NgRx",t[t.GraphQL=48]="GraphQL",t[t.PerformanceTrack=49]="PerformanceTrack",t[t.ResourceTiming=53]="ResourceTiming",t[t.ConnectionInformation=54]="ConnectionInformation",t[t.SetPageVisibility=55]="SetPageVisibility",t[t.LongTask=59]="LongTask",t[t.SetNodeAttributeURLBased=60]="SetNodeAttributeURLBased",t[t.SetCSSDataURLBased=61]="SetCSSDataURLBased",t[t.TechnicalInfo=63]="TechnicalInfo",t[t.CustomIssue=64]="CustomIssue",t[t.CSSInsertRuleURLBased=67]="CSSInsertRuleURLBased",t[t.MouseClick=69]="MouseClick",t[t.CreateIFrameDocument=70]="CreateIFrameDocument",t[t.AdoptedSSReplaceURLBased=71]="AdoptedSSReplaceURLBased",t[t.AdoptedSSInsertRuleURLBased=73]="AdoptedSSInsertRuleURLBased",t[t.AdoptedSSDeleteRule=75]="AdoptedSSDeleteRule",t[t.AdoptedSSAddOwner=76]="AdoptedSSAddOwner",t[t.AdoptedSSRemoveOwner=77]="AdoptedSSRemoveOwner"}(t||(t={}));class e{constructor(t,e,i,s=10,n=1e3){this.onUnauthorised=e,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=s,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(e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();if(e.status>=400)return void this.retry(t);this.attemptsCount=0;const i=this.queue.shift();i?this.sendBatch(i):this.busy=!1}).catch(e=>{console.warn("OpenReplay:",e),this.retry(t)})}clean(){this.queue.length=0}}const i="function"==typeof TextEncoder?new TextEncoder:{encode(t){const e=t.length,i=new Uint8Array(3*e);let s=-1;for(let n=0,r=0,h=0;h!==e;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===e){i[s+=1]=239,i[s+=1]=191,i[s+=1]=189;break}if(r=t.charCodeAt(h),!(r>=56320&&r<=57343)){i[s+=1]=239,i[s+=1]=191,i[s+=1]=189;continue}if(n=1024*(n-55296)+r-56320+65536,h+=1,n>65535){i[s+=1]=240|n>>>18,i[s+=1]=128|n>>>12&63,i[s+=1]=128|n>>>6&63,i[s+=1]=128|63&n;continue}}n<=127?i[s+=1]=0|n:n<=2047?(i[s+=1]=192|n>>>6,i[s+=1]=128|63&n):(i[s+=1]=224|n>>>12,i[s+=1]=128|n>>>6&63,i[s+=1]=128|63&n)}return i.subarray(0,s+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,e){this.data.set(t,e)}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 e=i.encode(t),s=e.byteLength;return!(!this.uint(s)||this.offset+s>this.size)&&(this.data.set(e,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}}{encode(e){switch(e[0]){case t.BatchMetadata:return this.uint(e[1])&&this.uint(e[2])&&this.uint(e[3])&&this.int(e[4])&&this.string(e[5]);case t.PartitionedMessage:return this.uint(e[1])&&this.uint(e[2]);case t.Timestamp:return this.uint(e[1]);case t.SetPageLocation:return this.string(e[1])&&this.string(e[2])&&this.uint(e[3]);case t.SetViewportSize:return this.uint(e[1])&&this.uint(e[2]);case t.SetViewportScroll:return this.int(e[1])&&this.int(e[2]);case t.CreateDocument:return!0;case t.CreateElementNode:return this.uint(e[1])&&this.uint(e[2])&&this.uint(e[3])&&this.string(e[4])&&this.boolean(e[5]);case t.CreateTextNode:case t.MoveNode:return this.uint(e[1])&&this.uint(e[2])&&this.uint(e[3]);case t.RemoveNode:return this.uint(e[1]);case t.SetNodeAttribute:return this.uint(e[1])&&this.string(e[2])&&this.string(e[3]);case t.RemoveNodeAttribute:case t.SetNodeData:return this.uint(e[1])&&this.string(e[2]);case t.SetNodeScroll:return this.uint(e[1])&&this.int(e[2])&&this.int(e[3]);case t.SetInputTarget:return this.uint(e[1])&&this.string(e[2]);case t.SetInputValue:return this.uint(e[1])&&this.string(e[2])&&this.int(e[3]);case t.SetInputChecked:return this.uint(e[1])&&this.boolean(e[2]);case t.MouseMove:return this.uint(e[1])&&this.uint(e[2]);case t.ConsoleLog:return this.string(e[1])&&this.string(e[2]);case t.PageLoadTiming:return this.uint(e[1])&&this.uint(e[2])&&this.uint(e[3])&&this.uint(e[4])&&this.uint(e[5])&&this.uint(e[6])&&this.uint(e[7])&&this.uint(e[8])&&this.uint(e[9]);case t.PageRenderTiming:return this.uint(e[1])&&this.uint(e[2])&&this.uint(e[3]);case t.JSException:return this.string(e[1])&&this.string(e[2])&&this.string(e[3]);case t.RawCustomEvent:return this.string(e[1])&&this.string(e[2]);case t.UserID:case t.UserAnonymousID:return this.string(e[1]);case t.Metadata:return this.string(e[1])&&this.string(e[2]);case t.CSSInsertRule:return this.uint(e[1])&&this.string(e[2])&&this.uint(e[3]);case t.CSSDeleteRule:return this.uint(e[1])&&this.uint(e[2]);case t.Fetch:return this.string(e[1])&&this.string(e[2])&&this.string(e[3])&&this.string(e[4])&&this.uint(e[5])&&this.uint(e[6])&&this.uint(e[7]);case t.Profiler:return this.string(e[1])&&this.uint(e[2])&&this.string(e[3])&&this.string(e[4]);case t.OTable:return this.string(e[1])&&this.string(e[2]);case t.StateAction:return this.string(e[1]);case t.Redux:return this.string(e[1])&&this.string(e[2])&&this.uint(e[3]);case t.Vuex:case t.MobX:return this.string(e[1])&&this.string(e[2]);case t.NgRx:return this.string(e[1])&&this.string(e[2])&&this.uint(e[3]);case t.GraphQL:return this.string(e[1])&&this.string(e[2])&&this.string(e[3])&&this.string(e[4]);case t.PerformanceTrack:return this.int(e[1])&&this.int(e[2])&&this.uint(e[3])&&this.uint(e[4]);case t.ResourceTiming:return this.uint(e[1])&&this.uint(e[2])&&this.uint(e[3])&&this.uint(e[4])&&this.uint(e[5])&&this.uint(e[6])&&this.string(e[7])&&this.string(e[8]);case t.ConnectionInformation:return this.uint(e[1])&&this.string(e[2]);case t.SetPageVisibility:return this.boolean(e[1]);case t.LongTask:return this.uint(e[1])&&this.uint(e[2])&&this.uint(e[3])&&this.uint(e[4])&&this.string(e[5])&&this.string(e[6])&&this.string(e[7]);case t.SetNodeAttributeURLBased:return this.uint(e[1])&&this.string(e[2])&&this.string(e[3])&&this.string(e[4]);case t.SetCSSDataURLBased:return this.uint(e[1])&&this.string(e[2])&&this.string(e[3]);case t.TechnicalInfo:case t.CustomIssue:return this.string(e[1])&&this.string(e[2]);case t.CSSInsertRuleURLBased:return this.uint(e[1])&&this.string(e[2])&&this.uint(e[3])&&this.string(e[4]);case t.MouseClick:return this.uint(e[1])&&this.uint(e[2])&&this.string(e[3])&&this.string(e[4]);case t.CreateIFrameDocument:return this.uint(e[1])&&this.uint(e[2]);case t.AdoptedSSReplaceURLBased:return this.uint(e[1])&&this.string(e[2])&&this.string(e[3]);case t.AdoptedSSInsertRuleURLBased:return this.uint(e[1])&&this.string(e[2])&&this.uint(e[3])&&this.string(e[4]);case t.AdoptedSSDeleteRule:case t.AdoptedSSAddOwner:case t.AdoptedSSRemoveOwner:return this.uint(e[1])&&this.uint(e[2])}}}class n{constructor(t,e,i,n){this.pageNo=t,this.timestamp=e,this.url=i,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,e){for(let e=0;e<3;e++)this.sizeBuffer[e]=t>>8*e;this.encoder.set(this.sizeBuffer,e)}prepare(){if(!this.encoder.isEmpty())return;const e=[t.BatchMetadata,1,this.pageNo,this.nextIndex,this.timestamp,this.url];this.writeType(e),this.writeFields(e),this.isEmpty=!0}writeWithSize(e){const i=this.encoder;if(!this.writeType(e)||!i.skip(3))return!1;const s=i.getCurrentOffset(),n=this.writeFields(e);if(n){const n=i.getCurrentOffset()-s;if(n>16777215)return console.warn("OpenReplay: max message size overflow."),!1;this.writeSizeAt(n,s-3),i.checkpoint(),this.isEmpty=this.isEmpty&&e[0]===t.Timestamp,this.nextIndex++}return n}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(e){if(e[0]===t.Timestamp&&(this.timestamp=e[1]),e[0]===t.SetPageLocation&&(this.url=e[1]),!this.writeWithSize(e))for(this.finaliseBatch();!this.writeWithSize(e);){if(this.beaconSize===this.beaconSizeLimit)return console.warn("OpenReplay: beacon size overflow. Skipping large message.",e),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 r;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active"}(r||(r={}));let h=null,a=null;function o(){a&&a.finaliseBatch()}function u(){r.Stopping,null!==d&&(clearInterval(d),d=null),a&&(a.clean(),a=null),r.NotActive}r.NotActive;let c,d=null;self.onmessage=({data:i})=>{if(null!=i){if("stop"===i)return o(),void u();if(Array.isArray(i)){if(!a)throw new Error("WebWorker: writer not initialised. Service Should be Started.");const e=a;i.forEach(i=>{i[0]===t.SetPageVisibility&&(i[1]?c=setTimeout(()=>self.postMessage("restart"),18e5):clearTimeout(c)),e.writeMessage(i)})}else{if("start"===i.type)return r.Starting,h=new e(i.ingestPoint,()=>{self.postMessage("restart")},()=>{h&&(h.clean(),h=null),u(),self.postMessage("failed")},i.connAttemptCount,i.connAttemptGap),a=new n(i.pageNo,i.timestamp,i.url,t=>h&&h.push(t)),null===d&&(d=setInterval(o,1e4)),r.Active;if("auth"===i.type){if(!h)throw new Error("WebWorker: sender not initialised. Received auth.");if(!a)throw new Error("WebWorker: writer not initialised. Received auth.");return h.authorise(i.token),void(i.beaconSizeLimit&&a.setBeaconSizeLimit(i.beaconSizeLimit))}}}else o()};'], { type: 'text/javascript' })));
|
|
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' })));
|
|
74
75
|
this.worker.onerror = (e) => {
|
|
75
76
|
this._debug('webworker_error', e);
|
|
76
77
|
};
|
|
@@ -149,20 +150,28 @@ export default class App {
|
|
|
149
150
|
}; // TODO: correct typing
|
|
150
151
|
}
|
|
151
152
|
attachCommitCallback(cb) {
|
|
153
|
+
// TODO!: what if start callback added when activityState === Active ?
|
|
154
|
+
// For example - attachEventListener() called during dynamic <iframe> appearance
|
|
152
155
|
this.commitCallbacks.push(cb);
|
|
153
156
|
}
|
|
154
|
-
attachStartCallback(cb) {
|
|
157
|
+
attachStartCallback(cb, useSafe = false) {
|
|
158
|
+
if (useSafe) {
|
|
159
|
+
cb = this.safe(cb);
|
|
160
|
+
}
|
|
155
161
|
this.startCallbacks.push(cb);
|
|
156
162
|
}
|
|
157
|
-
attachStopCallback(cb) {
|
|
163
|
+
attachStopCallback(cb, useSafe = false) {
|
|
164
|
+
if (useSafe) {
|
|
165
|
+
cb = this.safe(cb);
|
|
166
|
+
}
|
|
158
167
|
this.stopCallbacks.push(cb);
|
|
159
168
|
}
|
|
160
169
|
attachEventListener(target, type, listener, useSafe = true, useCapture = true) {
|
|
161
170
|
if (useSafe) {
|
|
162
171
|
listener = this.safe(listener);
|
|
163
172
|
}
|
|
164
|
-
this.attachStartCallback(() => target.addEventListener(type, listener, useCapture));
|
|
165
|
-
this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture));
|
|
173
|
+
this.attachStartCallback(() => target.addEventListener(type, listener, useCapture), useSafe);
|
|
174
|
+
this.attachStopCallback(() => target.removeEventListener(type, listener, useCapture), useSafe);
|
|
166
175
|
}
|
|
167
176
|
// TODO: full correct semantic
|
|
168
177
|
checkRequiredVersion(version) {
|
|
@@ -199,6 +208,14 @@ export default class App {
|
|
|
199
208
|
getSessionID() {
|
|
200
209
|
return this.session.getInfo().sessionID || undefined;
|
|
201
210
|
}
|
|
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
|
+
}
|
|
202
219
|
getHost() {
|
|
203
220
|
return new URL(this.options.ingestPoint).hostname;
|
|
204
221
|
}
|
|
@@ -248,6 +265,9 @@ export default class App {
|
|
|
248
265
|
return Promise.resolve(UnsuccessfulStart('OpenReplay: trying to call `start()` on the instance that has been started already.'));
|
|
249
266
|
}
|
|
250
267
|
this.activityState = ActivityState.Starting;
|
|
268
|
+
if (startOpts.sessionHash) {
|
|
269
|
+
this.session.applySessionHash(startOpts.sessionHash);
|
|
270
|
+
}
|
|
251
271
|
const timestamp = now();
|
|
252
272
|
const startWorkerMsg = {
|
|
253
273
|
type: 'start',
|
|
@@ -293,7 +313,7 @@ export default class App {
|
|
|
293
313
|
if (!this.worker) {
|
|
294
314
|
return Promise.reject('no worker found after start request (this might not happen)');
|
|
295
315
|
}
|
|
296
|
-
const { token, userUUID, sessionID, beaconSizeLimit, startTimestamp, // real startTS, derived from sessionID
|
|
316
|
+
const { token, userUUID, sessionID, projectID, beaconSizeLimit, startTimestamp, // real startTS, derived from sessionID
|
|
297
317
|
} = r;
|
|
298
318
|
if (typeof token !== 'string' ||
|
|
299
319
|
typeof userUUID !== 'string' ||
|
|
@@ -304,18 +324,18 @@ export default class App {
|
|
|
304
324
|
}
|
|
305
325
|
this.session.setSessionToken(token);
|
|
306
326
|
this.localStorage.setItem(this.options.local_uuid_key, userUUID);
|
|
307
|
-
this.session.update({ sessionID, timestamp: startTimestamp || timestamp }); // TODO: no no-explicit 'any'
|
|
327
|
+
this.session.update({ sessionID, timestamp: startTimestamp || timestamp, projectID }); // TODO: no no-explicit 'any'
|
|
308
328
|
const startWorkerMsg = {
|
|
309
329
|
type: 'auth',
|
|
310
330
|
token,
|
|
311
331
|
beaconSizeLimit,
|
|
312
332
|
};
|
|
313
333
|
this.worker.postMessage(startWorkerMsg);
|
|
314
|
-
this.activityState = ActivityState.Active;
|
|
315
334
|
const onStartInfo = { sessionToken: token, userUUID, sessionID };
|
|
316
335
|
this.startCallbacks.forEach((cb) => cb(onStartInfo)); // TODO: start as early as possible (before receiving the token)
|
|
317
336
|
this.observer.observe();
|
|
318
337
|
this.ticker.start();
|
|
338
|
+
this.activityState = ActivityState.Active;
|
|
319
339
|
this.notify.log('OpenReplay tracking started.');
|
|
320
340
|
// get rid of onStart ?
|
|
321
341
|
if (typeof this.options.onStart === 'function') {
|