Socket
Socket
Sign inDemoInstall

@openreplay/tracker

Package Overview
Dependencies
4
Maintainers
3
Versions
198
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 12.0.12 to 12.1.0-beta.99

cjs/app/workerManager/index.d.ts

13

cjs/app/index.d.ts

@@ -14,3 +14,3 @@ import FeatureFlags from '../modules/featureFlags.js';

import type { Options as NetworkOptions } from '../modules/network.js';
import type { Options as WebworkerOptions } from '../common/interaction.js';
import type { Options as WebworkerOptions, FromWorkerData } from '../common/interaction.js';
export interface StartOptions {

@@ -94,3 +94,3 @@ userID?: string;

private readonly version;
private readonly worker?;
private readonly workerManager?;
private compressionThreshold;

@@ -105,5 +105,6 @@ private restartAttempts;

featureFlags: FeatureFlags;
private tagWatcher;
private readonly tagWatcher;
constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>, signalError: (error: string, apis: string[]) => void);
private _debug;
handleWorkerMsg(data: FromWorkerData): void;
private readonly _debug;
private _usingOldFetchPlugin;

@@ -166,3 +167,3 @@ send(message: Message, urgent?: boolean): void;

* start buffering messages without starting the actual session, which gives
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger,
* and we will then send buffered batch, so it won't get lost

@@ -185,3 +186,3 @@ * */

*
* Then when this.offlineRecording is called, it will preload this messages and clear the storage item
* Then, when this.offlineRecording is called, it will preload this messages and clear the storage item
*

@@ -188,0 +189,0 @@ * Keeping the size of local storage reasonable is up to the end users of this library

@@ -47,2 +47,3 @@ "use strict";

const tagWatcher_js_1 = __importDefault(require("../modules/tagWatcher.js"));
const index_js_2 = __importDefault(require("./workerManager/index.js"));
const CANCELED = 'canceled';

@@ -84,3 +85,3 @@ const uxtStorageKey = 'or_uxt_active';

this.activityState = ActivityState.NotActive;
this.version = '12.0.12'; // TODO: version compatability check inside each plugin.
this.version = '12.1.0-beta.99'; // TODO: version compatability check inside each plugin.
this.compressionThreshold = 24 * 1000;

@@ -91,2 +92,16 @@ this.restartAttempts = 0;

this.conditionsManager = null;
this._debug = (context, e) => {
if (this.options.__debug_report_edp !== null) {
void fetch(this.options.__debug_report_edp, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
context,
// @ts-ignore
error: `${e}`,
}),
});
}
this.debug.error('OpenReplay error: ', context, e);
};
this._usingOldFetchPlugin = false;

@@ -181,47 +196,7 @@ this.coldStartCommitN = 0;

try {
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";class t{constructor(t,s,i,e=10,n=250,h,r){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.pageNo=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.lastBatchNum=0,this.ingestURL=t+"/v1/web/i",this.isCompressing=void 0!==h}getQueueStatus(){return 0===this.queue.length&&!this.busy}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){if(this.busy||!this.token)this.queue.push(t);else if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}}sendNext(){const t=this.queue.shift();if(t)if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}else this.busy=!1}retry(t,s,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s,i)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s,i){const e=i?.toString().replace(/^([^_]+)_([^_]+).*/,"$1_$2_$3");this.busy=!0;const n={Authorization:`Bearer ${this.token}`};s&&(n["Content-Encoding"]="gzip"),null!==this.token?fetch(`${this.ingestURL}?batch=${this.pageNo??"noPageNum"}_${e??"noBatchNum"}`,{body:t,method:"POST",headers:n,keepalive:t.length<65536}).then((e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();e.status>=400?this.retry(t,s,`${i??"noBatchNum"}_network:${e.status}`):(this.attemptsCount=0,this.sendNext())})).catch((e=>{console.warn("OpenReplay:",e),this.retry(t,s,`${i??"noBatchNum"}_reject:${e.message}`)})):setTimeout((()=>{this.sendBatch(t,s,`${i??"noBatchNum"}_newToken`)}),500)}sendCompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!0,s)}sendUncompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}clean(){this.sendNext(),setTimeout((()=>{this.token=null,this.queue.length=0}),10)}}const s="function"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let e=-1;for(let n=0,h=0,r=0;r!==s;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===s){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;break}if(h=t.charCodeAt(r),!(h>=56320&&h<=57343)){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;continue}if(n=1024*(n-55296)+h-56320+65536,r+=1,n>65535){i[e+=1]=240|n>>>18,i[e+=1]=128|n>>>12&63,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n;continue}}n<=127?i[e+=1]=0|n:n<=2047?(i[e+=1]=192|n>>>6,i[e+=1]=128|63&n):(i[e+=1]=224|n>>>12,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n)}return i.subarray(0,e+1)}};class i{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}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,s){this.data.set(t,s)}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=s.encode(t),e=i.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(i,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}}class e extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82: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:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54: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 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 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 63:case 64:case 79: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 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);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 48:case 78: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 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(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 67:case 73: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 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116: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])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4])}}}class n{constructor(t,s,i,n,h,r){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,this.onOfflineEnd=r,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new e(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,s){for(let s=0;s<3;s++)this.sizeBuffer[s]=t>>8*s;this.encoder.set(this.sizeBuffer,s)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],s=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(s),this.isEmpty=!0}writeWithSize(t){const s=this.encoder;if(!this.writeType(t)||!s.skip(3))return!1;const i=s.getCurrentOffset(),e=this.writeFields(t);if(e){const e=s.getCurrentOffset()-i;if(e>16777215)return console.warn("OpenReplay: max message size overflow."),!1;this.writeSizeAt(e,i-3),s.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if("q_end"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new e(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder=new e(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var h;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active",t[t.Stopped=4]="Stopped"}(h||(h={}));let r=null,a=null,u=h.NotActive;function o(){a&&a.finaliseBatch()}function c(){return new Promise((t=>{u=h.Stopping,null!==l&&(clearInterval(l),l=null),a&&(a.clean(),a=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{u=h.NotActive,t(null)}),100)}))}function p(){u!==h.Stopped&&(postMessage("a_stop"),c().then((()=>{postMessage("a_start")})))}let g,l=null;self.onmessage=({data:s})=>{if(null!=s){if("stop"===s)return o(),void c().then((()=>{u=h.Stopped}));if("forceFlushBatch"!==s){if(!Array.isArray(s)){if("compressed"===s.type){if(!r)return console.debug("OR WebWorker: sender not initialised. Compressed batch."),void p();s.batch&&r.sendCompressed(s.batch)}if("uncompressed"===s.type){if(!r)return console.debug("OR WebWorker: sender not initialised. Uncompressed batch."),void p();s.batch&&r.sendUncompressed(s.batch)}return"start"===s.type?(u=h.Starting,r=new t(s.ingestPoint,(()=>{p()}),(t=>{!function(t){postMessage({type:"failure",reason:t}),c()}(t)}),s.connAttemptCount,s.connAttemptGap,(t=>{postMessage({type:"compress",batch:t},[t.buffer])}),s.pageNo),a=new n(s.pageNo,s.timestamp,s.url,(t=>{r&&r.push(t)}),s.tabId,(()=>postMessage({type:"queue_empty"}))),null===l&&(l=setInterval(o,1e4)),u=h.Active):"auth"===s.type?r?a?(r.authorise(s.token),void(s.beaconSizeLimit&&a.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug("OR WebWorker: writer not initialised. Received auth."),void p()):(console.debug("OR WebWorker: sender not initialised. Received auth."),void p()):void 0}if(a){const t=a;s.forEach((s=>{55===s[0]&&(s[1]?g=setTimeout((()=>p()),18e5):clearTimeout(g)),t.writeMessage(s)}))}else postMessage("not_init"),p()}else o()}else o()};'], { type: 'text/javascript' })));
this.worker.onerror = (e) => {
this._debug('webworker_error', e);
};
this.worker.onmessage = ({ data }) => {
// handling 401 auth restart (new token assignment)
if (data === 'a_stop') {
this.stop(false);
}
else if (data === 'a_start') {
void this.start({}, true);
}
else if (data === 'not_init') {
this.debug.warn('OR WebWorker: writer not initialised. Restarting tracker');
}
else if (data.type === 'failure') {
this.stop(false);
this.debug.error('worker_failed', data.reason);
this._debug('worker_failed', data.reason);
}
else if (data.type === 'compress') {
const batch = data.batch;
const batchSize = batch.byteLength;
if (batchSize > this.compressionThreshold) {
(0, fflate_1.gzip)(data.batch, { mtime: 0 }, (err, result) => {
if (err) {
this.debug.error('Openreplay compression error:', err);
this.worker?.postMessage({ type: 'uncompressed', batch: batch });
}
else {
this.worker?.postMessage({ type: 'compressed', batch: result });
}
});
}
else {
this.worker?.postMessage({ type: 'uncompressed', batch: batch });
}
}
else if (data.type === 'queue_empty') {
this.onSessionSent();
}
};
const webworker = new Worker(URL.createObjectURL(new Blob(['"use strict";const t="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 i{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}get 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(i){const s=t.encode(i),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}}class s extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82: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:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54: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 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 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 63:case 64:case 79: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 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);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 48:case 78: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 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(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 67:case 73: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 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116: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])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4])}}}class e{constructor(t,i,e,n,r,h){this.pageNo=t,this.timestamp=i,this.url=e,this.onBatch=n,this.tabId=r,this.onOfflineEnd=h,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],i=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(i),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("q_end"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new s(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder=new s(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),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",t[t.Stopped=4]="Stopped"}(n||(n={}));let r=null,h=n.NotActive;function a(t){postMessage({type:"status",data:t}),h=t}function u(){r&&r.finaliseBatch()}function c(){a(n.Stopping),null!==f&&(clearInterval(f),f=null),r&&(r.clean(),r=null),setTimeout((()=>{a(n.NotActive)}),100)}function o(){h!==n.Stopped&&(postMessage({type:"restart"}),c())}let f=null;self.onmessage=({data:t})=>{if(null!=t){if("writer_finalize"===t.type)return u(),h=n.Stopped;if("reset_writer"!==t.type){if("forceFlushBatch"!==t.type){if("to_writer"===t.type){let i=!1;t.data.forEach((t=>{r?r.writeMessage(t):i||(i=!0,postMessage({type:"not_init"}),o())}))}return"start"===t.type?(h=n.Starting,r=new e(t.pageNo,t.timestamp,t.url,(t=>{postMessage({type:"batch_ready",data:t},[t.buffer])}),t.tabId,(()=>postMessage({type:"queue_empty"}))),null===f&&(f=setInterval(u,1e4)),h=n.Active):"beacon_size_limit"===t.type?r?void(t.beaconSizeLimit&&r.setBeaconSizeLimit(t.beaconSizeLimit)):(console.debug("OR WebWorker: writer not initialised. Received auth."),void o()):void("restart"===t.type&&o())}u()}else c()}else u()};'], { type: 'text/javascript' })));
this.workerManager = new index_js_2.default(this, webworker, this._debug);
const alertWorker = () => {
if (this.worker) {
this.worker.postMessage(null);
if (this.workerManager) {
this.workerManager.processMessage(null);
}

@@ -245,3 +220,3 @@ };

// you stole someone's identity
reg: 'never-gonna-run-around-and-desert-you',
regen: 'never-gonna-run-around-and-desert-you',
};

@@ -264,3 +239,3 @@ if (this.bc) {

}
if (ev.data.line === proto.reg) {
if (ev.data.line === proto.regen) {
const sessionToken = ev.data.token;

@@ -274,3 +249,3 @@ this.session.regenerateTabId();

this.bc.postMessage({
line: ev.data.source === thisTab ? proto.reg : proto.resp,
line: ev.data.source === thisTab ? proto.regen : proto.resp,
token,

@@ -285,15 +260,40 @@ source: thisTab,

}
_debug(context, e) {
if (this.options.__debug_report_edp !== null) {
void fetch(this.options.__debug_report_edp, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
context,
// @ts-ignore
error: `${e}`,
}),
});
handleWorkerMsg(data) {
if (data.type === 'restart') {
this.stop(false);
void this.start({}, true);
}
this.debug.error('OpenReplay error: ', context, e);
else if (data.type === 'not_init') {
this.debug.warn('OR WebWorker: writer not initialised; restarting worker');
}
else if (data.type === 'failure') {
this.stop(false);
this.debug.error('worker_failed', data.reason);
this._debug('worker_failed', data.reason);
}
else if (data.type === 'compress') {
const batch = data.batch;
const batchSize = batch.byteLength;
if (batchSize > this.compressionThreshold) {
(0, fflate_1.gzip)(data.batch, { mtime: 0 }, (err, result) => {
if (err) {
this.debug.error('Openreplay compression error:', err);
this.stop(false);
if (this.restartAttempts < 3) {
this.restartAttempts += 1;
void this.start({}, true);
}
}
else {
this.workerManager?.sendCompressedBatch(result);
}
});
}
else {
this.workerManager?.sendUncompressedBatch(batch);
}
}
else if (data.type === 'queue_empty') {
this.onSessionSent();
}
}

@@ -338,20 +338,11 @@ send(message, urgent = false) {

_nCommit() {
if (this.worker !== undefined && this.messages.length) {
try {
(0, utils_js_1.requestIdleCb)(() => {
this.messages.unshift((0, messages_gen_js_2.TabData)(this.session.getTabId()));
this.messages.unshift((0, messages_gen_js_2.Timestamp)(this.timestamp()));
// why I need to add opt chaining?
this.worker?.postMessage(this.messages);
this.commitCallbacks.forEach((cb) => cb(this.messages));
this.messages.length = 0;
});
}
catch (e) {
this._debug('worker_commit', e);
this.stop(true);
setTimeout(() => {
void this.start();
}, 500);
}
if (this.workerManager !== undefined && this.messages.length) {
(0, utils_js_1.requestIdleCb)(() => {
this.messages.unshift((0, messages_gen_js_2.TabData)(this.session.getTabId()));
this.messages.unshift((0, messages_gen_js_2.Timestamp)(this.timestamp()));
// why I need to add opt chaining?
this.workerManager?.processMessage({ type: 'batch', data: this.messages });
this.commitCallbacks.forEach((cb) => cb(this.messages));
this.messages.length = 0;
});
}

@@ -384,3 +375,3 @@ }

postToWorker(messages) {
this.worker?.postMessage(messages);
this.workerManager?.processMessage({ type: 'batch', data: messages });
this.commitCallbacks.forEach((cb) => cb(messages));

@@ -532,3 +523,3 @@ messages.length = 0;

* start buffering messages without starting the actual session, which gives
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger,
* and we will then send buffered batch, so it won't get lost

@@ -669,3 +660,3 @@ * */

*
* Then when this.offlineRecording is called, it will preload this messages and clear the storage item
* Then, when this.offlineRecording is called, it will preload this messages and clear the storage item
*

@@ -699,3 +690,3 @@ * Keeping the size of local storage reasonable is up to the end users of this library

const timestamp = (0, utils_js_1.now)();
this.worker?.postMessage({
this.workerManager?.processMessage({
type: 'start',

@@ -728,4 +719,3 @@ pageNo: this.session.incPageNo(),

const { token, userBrowser, userCity, userCountry, userDevice, userOS, userState, beaconSizeLimit, projectID, } = await r.json();
this.worker?.postMessage({
type: 'auth',
this.workerManager?.authorizeWorker({
token,

@@ -754,3 +744,3 @@ beaconSizeLimit,

}
if (!this.worker) {
if (!this.workerManager) {
const reason = 'No worker found: perhaps, CSP is not set.';

@@ -782,3 +772,3 @@ this.signalError(reason, []);

const timestamp = (0, utils_js_1.now)();
this.worker.postMessage({
this.workerManager?.startWorker({
type: 'start',

@@ -829,3 +819,3 @@ pageNo: this.session.incPageNo(),

.then(async (r) => {
if (!this.worker) {
if (!this.workerManager) {
const reason = 'no worker found after start request (this might not happen)';

@@ -870,4 +860,3 @@ this.signalError(reason, []);

});
this.worker.postMessage({
type: 'auth',
this.workerManager?.authorizeWorker({
token,

@@ -1007,3 +996,3 @@ beaconSizeLimit,

forceFlushBatch() {
this.worker?.postMessage('forceFlushBatch');
this.workerManager?.processMessage({ type: 'forceFlushBatch' });
}

@@ -1045,4 +1034,4 @@ getTabId() {

this.tagWatcher.clear();
if (this.worker && stopWorker) {
this.worker.postMessage('stop');
if (this.workerManager && stopWorker) {
this.workerManager?.stopWorker();
}

@@ -1049,0 +1038,0 @@ this.canvasRecorder?.clear();

@@ -6,3 +6,57 @@ import Message from './messages.gen.js';

}
type Start = {
export type ToWorkerData = null | Stop | Batch | WorkerStart | BeaconSizeLimit | ToWriterData | ForceFlushBatch | CheckQueue | ResetWriter | WriterFinalize;
export type FromWorkerData = Restart | Failure | NotInit | Compress | QEmpty | Status | BatchReady;
type BatchReady = {
type: 'batch_ready';
data: Uint8Array;
};
type Status = {
type: 'status';
data: number;
};
type Compress = {
type: 'compress';
batch: Uint8Array;
};
type Restart = {
type: 'restart';
};
type NotInit = {
type: 'not_init';
};
type Stop = {
type: 'stop';
};
type Batch = {
type: 'batch';
data: Array<Message>;
};
type ForceFlushBatch = {
type: 'forceFlushBatch';
};
type CheckQueue = {
type: 'check_queue';
};
type WriterFinalize = {
type: 'writer_finalize';
};
type ResetWriter = {
type: 'reset_writer';
};
type BeaconSizeLimit = {
type: 'beacon_size_limit';
data: number;
};
type ToWriterData = {
type: 'to_writer';
data: Array<Message>;
};
type Failure = {
type: 'failure';
reason: string;
};
type QEmpty = {
type: 'queue_empty';
};
export type WorkerStart = {
type: 'start';

@@ -15,25 +69,6 @@ ingestPoint: string;

} & Options;
type Auth = {
type: 'auth';
export type WorkerAuth = {
token: string;
beaconSizeLimit?: number;
};
export type ToWorkerData = null | 'stop' | Start | Auth | Array<Message> | {
type: 'compressed';
batch: Uint8Array;
} | {
type: 'uncompressed';
batch: Uint8Array;
} | 'forceFlushBatch' | 'check_queue';
type Failure = {
type: 'failure';
reason: string;
};
type QEmpty = {
type: 'queue_empty';
};
export type FromWorkerData = 'a_stop' | 'a_start' | Failure | 'not_init' | {
type: 'compress';
batch: Uint8Array;
} | QEmpty;
export {};

@@ -100,3 +100,3 @@ "use strict";

req.send(JSON.stringify({
trackerVersion: '12.0.12',
trackerVersion: '12.1.0-beta.99',
projectKey: this.options.projectKey,

@@ -103,0 +103,0 @@ doNotTrack,

@@ -14,3 +14,3 @@ import FeatureFlags from '../modules/featureFlags.js';

import type { Options as NetworkOptions } from '../modules/network.js';
import type { Options as WebworkerOptions } from '../common/interaction.js';
import type { Options as WebworkerOptions, FromWorkerData } from '../common/interaction.js';
export interface StartOptions {

@@ -94,3 +94,3 @@ userID?: string;

private readonly version;
private readonly worker?;
private readonly workerManager?;
private compressionThreshold;

@@ -105,5 +105,6 @@ private restartAttempts;

featureFlags: FeatureFlags;
private tagWatcher;
private readonly tagWatcher;
constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>, signalError: (error: string, apis: string[]) => void);
private _debug;
handleWorkerMsg(data: FromWorkerData): void;
private readonly _debug;
private _usingOldFetchPlugin;

@@ -166,3 +167,3 @@ send(message: Message, urgent?: boolean): void;

* start buffering messages without starting the actual session, which gives
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger,
* and we will then send buffered batch, so it won't get lost

@@ -185,3 +186,3 @@ * */

*
* Then when this.offlineRecording is called, it will preload this messages and clear the storage item
* Then, when this.offlineRecording is called, it will preload this messages and clear the storage item
*

@@ -188,0 +189,0 @@ * Keeping the size of local storage reasonable is up to the end users of this library

@@ -18,2 +18,3 @@ import ConditionsManager from '../modules/conditionsManager.js';

import TagWatcher from '../modules/tagWatcher.js';
import WebWorkerManager from './workerManager/index.js';
const CANCELED = 'canceled';

@@ -55,3 +56,3 @@ const uxtStorageKey = 'or_uxt_active';

this.activityState = ActivityState.NotActive;
this.version = '12.0.12'; // TODO: version compatability check inside each plugin.
this.version = '12.1.0-beta.99'; // TODO: version compatability check inside each plugin.
this.compressionThreshold = 24 * 1000;

@@ -62,2 +63,16 @@ this.restartAttempts = 0;

this.conditionsManager = null;
this._debug = (context, e) => {
if (this.options.__debug_report_edp !== null) {
void fetch(this.options.__debug_report_edp, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
context,
// @ts-ignore
error: `${e}`,
}),
});
}
this.debug.error('OpenReplay error: ', context, e);
};
this._usingOldFetchPlugin = false;

@@ -152,47 +167,7 @@ this.coldStartCommitN = 0;

try {
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";class t{constructor(t,s,i,e=10,n=250,h,r){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.pageNo=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.lastBatchNum=0,this.ingestURL=t+"/v1/web/i",this.isCompressing=void 0!==h}getQueueStatus(){return 0===this.queue.length&&!this.busy}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){if(this.busy||!this.token)this.queue.push(t);else if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}}sendNext(){const t=this.queue.shift();if(t)if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}else this.busy=!1}retry(t,s,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s,i)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s,i){const e=i?.toString().replace(/^([^_]+)_([^_]+).*/,"$1_$2_$3");this.busy=!0;const n={Authorization:`Bearer ${this.token}`};s&&(n["Content-Encoding"]="gzip"),null!==this.token?fetch(`${this.ingestURL}?batch=${this.pageNo??"noPageNum"}_${e??"noBatchNum"}`,{body:t,method:"POST",headers:n,keepalive:t.length<65536}).then((e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();e.status>=400?this.retry(t,s,`${i??"noBatchNum"}_network:${e.status}`):(this.attemptsCount=0,this.sendNext())})).catch((e=>{console.warn("OpenReplay:",e),this.retry(t,s,`${i??"noBatchNum"}_reject:${e.message}`)})):setTimeout((()=>{this.sendBatch(t,s,`${i??"noBatchNum"}_newToken`)}),500)}sendCompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!0,s)}sendUncompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}clean(){this.sendNext(),setTimeout((()=>{this.token=null,this.queue.length=0}),10)}}const s="function"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let e=-1;for(let n=0,h=0,r=0;r!==s;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===s){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;break}if(h=t.charCodeAt(r),!(h>=56320&&h<=57343)){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;continue}if(n=1024*(n-55296)+h-56320+65536,r+=1,n>65535){i[e+=1]=240|n>>>18,i[e+=1]=128|n>>>12&63,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n;continue}}n<=127?i[e+=1]=0|n:n<=2047?(i[e+=1]=192|n>>>6,i[e+=1]=128|63&n):(i[e+=1]=224|n>>>12,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n)}return i.subarray(0,e+1)}};class i{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}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,s){this.data.set(t,s)}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=s.encode(t),e=i.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(i,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}}class e extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82: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:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54: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 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 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 63:case 64:case 79: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 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);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 48:case 78: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 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(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 67:case 73: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 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116: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])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4])}}}class n{constructor(t,s,i,n,h,r){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,this.onOfflineEnd=r,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new e(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,s){for(let s=0;s<3;s++)this.sizeBuffer[s]=t>>8*s;this.encoder.set(this.sizeBuffer,s)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],s=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(s),this.isEmpty=!0}writeWithSize(t){const s=this.encoder;if(!this.writeType(t)||!s.skip(3))return!1;const i=s.getCurrentOffset(),e=this.writeFields(t);if(e){const e=s.getCurrentOffset()-i;if(e>16777215)return console.warn("OpenReplay: max message size overflow."),!1;this.writeSizeAt(e,i-3),s.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if("q_end"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new e(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder=new e(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var h;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active",t[t.Stopped=4]="Stopped"}(h||(h={}));let r=null,a=null,u=h.NotActive;function o(){a&&a.finaliseBatch()}function c(){return new Promise((t=>{u=h.Stopping,null!==l&&(clearInterval(l),l=null),a&&(a.clean(),a=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{u=h.NotActive,t(null)}),100)}))}function p(){u!==h.Stopped&&(postMessage("a_stop"),c().then((()=>{postMessage("a_start")})))}let g,l=null;self.onmessage=({data:s})=>{if(null!=s){if("stop"===s)return o(),void c().then((()=>{u=h.Stopped}));if("forceFlushBatch"!==s){if(!Array.isArray(s)){if("compressed"===s.type){if(!r)return console.debug("OR WebWorker: sender not initialised. Compressed batch."),void p();s.batch&&r.sendCompressed(s.batch)}if("uncompressed"===s.type){if(!r)return console.debug("OR WebWorker: sender not initialised. Uncompressed batch."),void p();s.batch&&r.sendUncompressed(s.batch)}return"start"===s.type?(u=h.Starting,r=new t(s.ingestPoint,(()=>{p()}),(t=>{!function(t){postMessage({type:"failure",reason:t}),c()}(t)}),s.connAttemptCount,s.connAttemptGap,(t=>{postMessage({type:"compress",batch:t},[t.buffer])}),s.pageNo),a=new n(s.pageNo,s.timestamp,s.url,(t=>{r&&r.push(t)}),s.tabId,(()=>postMessage({type:"queue_empty"}))),null===l&&(l=setInterval(o,1e4)),u=h.Active):"auth"===s.type?r?a?(r.authorise(s.token),void(s.beaconSizeLimit&&a.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug("OR WebWorker: writer not initialised. Received auth."),void p()):(console.debug("OR WebWorker: sender not initialised. Received auth."),void p()):void 0}if(a){const t=a;s.forEach((s=>{55===s[0]&&(s[1]?g=setTimeout((()=>p()),18e5):clearTimeout(g)),t.writeMessage(s)}))}else postMessage("not_init"),p()}else o()}else o()};'], { type: 'text/javascript' })));
this.worker.onerror = (e) => {
this._debug('webworker_error', e);
};
this.worker.onmessage = ({ data }) => {
// handling 401 auth restart (new token assignment)
if (data === 'a_stop') {
this.stop(false);
}
else if (data === 'a_start') {
void this.start({}, true);
}
else if (data === 'not_init') {
this.debug.warn('OR WebWorker: writer not initialised. Restarting tracker');
}
else if (data.type === 'failure') {
this.stop(false);
this.debug.error('worker_failed', data.reason);
this._debug('worker_failed', data.reason);
}
else if (data.type === 'compress') {
const batch = data.batch;
const batchSize = batch.byteLength;
if (batchSize > this.compressionThreshold) {
gzip(data.batch, { mtime: 0 }, (err, result) => {
if (err) {
this.debug.error('Openreplay compression error:', err);
this.worker?.postMessage({ type: 'uncompressed', batch: batch });
}
else {
this.worker?.postMessage({ type: 'compressed', batch: result });
}
});
}
else {
this.worker?.postMessage({ type: 'uncompressed', batch: batch });
}
}
else if (data.type === 'queue_empty') {
this.onSessionSent();
}
};
const webworker = new Worker(URL.createObjectURL(new Blob(['"use strict";const t="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 i{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}get 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(i){const s=t.encode(i),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}}class s extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82: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:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54: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 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 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 63:case 64:case 79: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 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);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 48:case 78: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 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(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 67:case 73: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 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116: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])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4])}}}class e{constructor(t,i,e,n,r,h){this.pageNo=t,this.timestamp=i,this.url=e,this.onBatch=n,this.tabId=r,this.onOfflineEnd=h,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],i=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(i),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("q_end"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new s(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder=new s(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),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",t[t.Stopped=4]="Stopped"}(n||(n={}));let r=null,h=n.NotActive;function a(t){postMessage({type:"status",data:t}),h=t}function u(){r&&r.finaliseBatch()}function c(){a(n.Stopping),null!==f&&(clearInterval(f),f=null),r&&(r.clean(),r=null),setTimeout((()=>{a(n.NotActive)}),100)}function o(){h!==n.Stopped&&(postMessage({type:"restart"}),c())}let f=null;self.onmessage=({data:t})=>{if(null!=t){if("writer_finalize"===t.type)return u(),h=n.Stopped;if("reset_writer"!==t.type){if("forceFlushBatch"!==t.type){if("to_writer"===t.type){let i=!1;t.data.forEach((t=>{r?r.writeMessage(t):i||(i=!0,postMessage({type:"not_init"}),o())}))}return"start"===t.type?(h=n.Starting,r=new e(t.pageNo,t.timestamp,t.url,(t=>{postMessage({type:"batch_ready",data:t},[t.buffer])}),t.tabId,(()=>postMessage({type:"queue_empty"}))),null===f&&(f=setInterval(u,1e4)),h=n.Active):"beacon_size_limit"===t.type?r?void(t.beaconSizeLimit&&r.setBeaconSizeLimit(t.beaconSizeLimit)):(console.debug("OR WebWorker: writer not initialised. Received auth."),void o()):void("restart"===t.type&&o())}u()}else c()}else u()};'], { type: 'text/javascript' })));
this.workerManager = new WebWorkerManager(this, webworker, this._debug);
const alertWorker = () => {
if (this.worker) {
this.worker.postMessage(null);
if (this.workerManager) {
this.workerManager.processMessage(null);
}

@@ -216,3 +191,3 @@ };

// you stole someone's identity
reg: 'never-gonna-run-around-and-desert-you',
regen: 'never-gonna-run-around-and-desert-you',
};

@@ -235,3 +210,3 @@ if (this.bc) {

}
if (ev.data.line === proto.reg) {
if (ev.data.line === proto.regen) {
const sessionToken = ev.data.token;

@@ -245,3 +220,3 @@ this.session.regenerateTabId();

this.bc.postMessage({
line: ev.data.source === thisTab ? proto.reg : proto.resp,
line: ev.data.source === thisTab ? proto.regen : proto.resp,
token,

@@ -256,15 +231,40 @@ source: thisTab,

}
_debug(context, e) {
if (this.options.__debug_report_edp !== null) {
void fetch(this.options.__debug_report_edp, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
context,
// @ts-ignore
error: `${e}`,
}),
});
handleWorkerMsg(data) {
if (data.type === 'restart') {
this.stop(false);
void this.start({}, true);
}
this.debug.error('OpenReplay error: ', context, e);
else if (data.type === 'not_init') {
this.debug.warn('OR WebWorker: writer not initialised; restarting worker');
}
else if (data.type === 'failure') {
this.stop(false);
this.debug.error('worker_failed', data.reason);
this._debug('worker_failed', data.reason);
}
else if (data.type === 'compress') {
const batch = data.batch;
const batchSize = batch.byteLength;
if (batchSize > this.compressionThreshold) {
gzip(data.batch, { mtime: 0 }, (err, result) => {
if (err) {
this.debug.error('Openreplay compression error:', err);
this.stop(false);
if (this.restartAttempts < 3) {
this.restartAttempts += 1;
void this.start({}, true);
}
}
else {
this.workerManager?.sendCompressedBatch(result);
}
});
}
else {
this.workerManager?.sendUncompressedBatch(batch);
}
}
else if (data.type === 'queue_empty') {
this.onSessionSent();
}
}

@@ -309,20 +309,11 @@ send(message, urgent = false) {

_nCommit() {
if (this.worker !== undefined && this.messages.length) {
try {
requestIdleCb(() => {
this.messages.unshift(TabData(this.session.getTabId()));
this.messages.unshift(Timestamp(this.timestamp()));
// why I need to add opt chaining?
this.worker?.postMessage(this.messages);
this.commitCallbacks.forEach((cb) => cb(this.messages));
this.messages.length = 0;
});
}
catch (e) {
this._debug('worker_commit', e);
this.stop(true);
setTimeout(() => {
void this.start();
}, 500);
}
if (this.workerManager !== undefined && this.messages.length) {
requestIdleCb(() => {
this.messages.unshift(TabData(this.session.getTabId()));
this.messages.unshift(Timestamp(this.timestamp()));
// why I need to add opt chaining?
this.workerManager?.processMessage({ type: 'batch', data: this.messages });
this.commitCallbacks.forEach((cb) => cb(this.messages));
this.messages.length = 0;
});
}

@@ -355,3 +346,3 @@ }

postToWorker(messages) {
this.worker?.postMessage(messages);
this.workerManager?.processMessage({ type: 'batch', data: messages });
this.commitCallbacks.forEach((cb) => cb(messages));

@@ -503,3 +494,3 @@ messages.length = 0;

* start buffering messages without starting the actual session, which gives
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger,
* and we will then send buffered batch, so it won't get lost

@@ -640,3 +631,3 @@ * */

*
* Then when this.offlineRecording is called, it will preload this messages and clear the storage item
* Then, when this.offlineRecording is called, it will preload this messages and clear the storage item
*

@@ -670,3 +661,3 @@ * Keeping the size of local storage reasonable is up to the end users of this library

const timestamp = now();
this.worker?.postMessage({
this.workerManager?.processMessage({
type: 'start',

@@ -699,4 +690,3 @@ pageNo: this.session.incPageNo(),

const { token, userBrowser, userCity, userCountry, userDevice, userOS, userState, beaconSizeLimit, projectID, } = await r.json();
this.worker?.postMessage({
type: 'auth',
this.workerManager?.authorizeWorker({
token,

@@ -725,3 +715,3 @@ beaconSizeLimit,

}
if (!this.worker) {
if (!this.workerManager) {
const reason = 'No worker found: perhaps, CSP is not set.';

@@ -753,3 +743,3 @@ this.signalError(reason, []);

const timestamp = now();
this.worker.postMessage({
this.workerManager?.startWorker({
type: 'start',

@@ -800,3 +790,3 @@ pageNo: this.session.incPageNo(),

.then(async (r) => {
if (!this.worker) {
if (!this.workerManager) {
const reason = 'no worker found after start request (this might not happen)';

@@ -841,4 +831,3 @@ this.signalError(reason, []);

});
this.worker.postMessage({
type: 'auth',
this.workerManager?.authorizeWorker({
token,

@@ -978,3 +967,3 @@ beaconSizeLimit,

forceFlushBatch() {
this.worker?.postMessage('forceFlushBatch');
this.workerManager?.processMessage({ type: 'forceFlushBatch' });
}

@@ -1016,4 +1005,4 @@ getTabId() {

this.tagWatcher.clear();
if (this.worker && stopWorker) {
this.worker.postMessage('stop');
if (this.workerManager && stopWorker) {
this.workerManager?.stopWorker();
}

@@ -1020,0 +1009,0 @@ this.canvasRecorder?.clear();

@@ -6,3 +6,57 @@ import Message from './messages.gen.js';

}
type Start = {
export type ToWorkerData = null | Stop | Batch | WorkerStart | BeaconSizeLimit | ToWriterData | ForceFlushBatch | CheckQueue | ResetWriter | WriterFinalize;
export type FromWorkerData = Restart | Failure | NotInit | Compress | QEmpty | Status | BatchReady;
type BatchReady = {
type: 'batch_ready';
data: Uint8Array;
};
type Status = {
type: 'status';
data: number;
};
type Compress = {
type: 'compress';
batch: Uint8Array;
};
type Restart = {
type: 'restart';
};
type NotInit = {
type: 'not_init';
};
type Stop = {
type: 'stop';
};
type Batch = {
type: 'batch';
data: Array<Message>;
};
type ForceFlushBatch = {
type: 'forceFlushBatch';
};
type CheckQueue = {
type: 'check_queue';
};
type WriterFinalize = {
type: 'writer_finalize';
};
type ResetWriter = {
type: 'reset_writer';
};
type BeaconSizeLimit = {
type: 'beacon_size_limit';
data: number;
};
type ToWriterData = {
type: 'to_writer';
data: Array<Message>;
};
type Failure = {
type: 'failure';
reason: string;
};
type QEmpty = {
type: 'queue_empty';
};
export type WorkerStart = {
type: 'start';

@@ -15,25 +69,6 @@ ingestPoint: string;

} & Options;
type Auth = {
type: 'auth';
export type WorkerAuth = {
token: string;
beaconSizeLimit?: number;
};
export type ToWorkerData = null | 'stop' | Start | Auth | Array<Message> | {
type: 'compressed';
batch: Uint8Array;
} | {
type: 'uncompressed';
batch: Uint8Array;
} | 'forceFlushBatch' | 'check_queue';
type Failure = {
type: 'failure';
reason: string;
};
type QEmpty = {
type: 'queue_empty';
};
export type FromWorkerData = 'a_stop' | 'a_start' | Failure | 'not_init' | {
type: 'compress';
batch: Uint8Array;
} | QEmpty;
export {};

@@ -69,3 +69,3 @@ import App, { DEFAULT_INGEST_POINT } from './app/index.js';

req.send(JSON.stringify({
trackerVersion: '12.0.12',
trackerVersion: '12.1.0-beta.99',
projectKey: this.options.projectKey,

@@ -72,0 +72,0 @@ doNotTrack,

{
"name": "@openreplay/tracker",
"description": "The OpenReplay tracker main package",
"version": "12.0.12",
"version": "12.1.0-beta.99",
"keywords": [

@@ -6,0 +6,0 @@ "logging",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc