@openreplay/tracker 9.0.12 → 10.0.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/.nvmrc +1 -0
- package/CHANGELOG.md +7 -0
- package/README.md +4 -0
- package/bun.lockb +0 -0
- package/cjs/app/index.js +14 -11
- package/cjs/app/logger.d.ts +1 -1
- package/cjs/app/messages.gen.d.ts +2 -1
- package/cjs/app/messages.gen.js +20 -5
- package/cjs/app/nodes.js +4 -3
- package/cjs/app/observer/observer.js +2 -1
- package/cjs/common/messages.gen.d.ts +17 -4
- package/cjs/index.js +1 -1
- package/cjs/modules/Network/beaconProxy.d.ts +16 -0
- package/cjs/modules/Network/beaconProxy.js +82 -0
- package/cjs/modules/Network/fetchProxy.d.ts +0 -1
- package/cjs/modules/Network/fetchProxy.js +0 -1
- package/cjs/modules/Network/index.js +5 -0
- package/cjs/modules/Network/networkMessage.d.ts +1 -1
- package/cjs/modules/Network/networkMessage.js +1 -1
- package/cjs/modules/Network/xhrProxy.d.ts +0 -9
- package/cjs/modules/Network/xhrProxy.js +0 -1
- package/cjs/modules/axiosSpy.js +1 -1
- package/cjs/modules/constructedStyleSheets.js +25 -21
- package/cjs/modules/featureFlags.js +0 -1
- package/cjs/modules/img.js +2 -2
- package/cjs/modules/network.js +3 -2
- package/cjs/utils.d.ts +16 -0
- package/cjs/utils.js +53 -1
- package/coverage/clover.xml +533 -772
- package/coverage/coverage-final.json +8 -12
- package/coverage/lcov-report/index.html +27 -42
- package/coverage/lcov-report/main/app/guards.ts.html +1 -1
- package/coverage/lcov-report/main/app/index.html +14 -14
- package/coverage/lcov-report/main/app/index.ts.html +196 -28
- package/coverage/lcov-report/main/app/logger.ts.html +1 -1
- package/coverage/lcov-report/main/app/messages.gen.ts.html +1 -1
- package/coverage/lcov-report/main/app/nodes.ts.html +13 -7
- package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/index.html +1 -1
- package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/top_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/sanitizer.ts.html +1 -1
- package/coverage/lcov-report/main/app/session.ts.html +20 -8
- package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
- package/coverage/lcov-report/main/index.html +23 -23
- package/coverage/lcov-report/main/index.ts.html +26 -26
- package/coverage/lcov-report/main/modules/Network/beaconProxy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/index.html +1 -1
- package/coverage/lcov-report/main/modules/Network/index.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/networkMessage.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/utils.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/attributeSender.ts.html +1 -1
- package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/console.ts.html +1 -1
- package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +42 -30
- package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
- package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
- package/coverage/lcov-report/main/modules/featureFlags.ts.html +1 -1
- package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
- package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
- package/coverage/lcov-report/main/modules/img.ts.html +23 -20
- package/coverage/lcov-report/main/modules/index.html +12 -12
- package/coverage/lcov-report/main/modules/input.ts.html +1 -1
- package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
- package/coverage/lcov-report/main/modules/network.ts.html +1 -1
- package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
- package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
- package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
- package/coverage/lcov-report/main/modules/timing.ts.html +30 -6
- package/coverage/lcov-report/main/modules/viewport.ts.html +1 -1
- package/coverage/lcov-report/main/utils.ts.html +269 -44
- package/coverage/lcov-report/webworker/BatchWriter.ts.html +1 -1
- package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +1 -1
- package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +1 -1
- package/coverage/lcov-report/webworker/QueueSender.ts.html +1 -1
- package/coverage/lcov-report/webworker/index.html +1 -1
- package/coverage/lcov-report/webworker/index.ts.html +1 -1
- package/coverage/lcov.info +920 -1285
- package/lib/app/index.js +15 -12
- package/lib/app/logger.d.ts +1 -1
- package/lib/app/messages.gen.d.ts +2 -1
- package/lib/app/messages.gen.js +16 -2
- package/lib/app/nodes.js +4 -3
- package/lib/app/observer/observer.js +2 -1
- package/lib/common/messages.gen.d.ts +17 -4
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/index.js +1 -1
- package/lib/modules/Network/beaconProxy.d.ts +16 -0
- package/lib/modules/Network/beaconProxy.js +77 -0
- package/lib/modules/Network/fetchProxy.d.ts +0 -1
- package/lib/modules/Network/fetchProxy.js +0 -1
- package/lib/modules/Network/index.js +5 -0
- package/lib/modules/Network/networkMessage.d.ts +1 -1
- package/lib/modules/Network/networkMessage.js +1 -1
- package/lib/modules/Network/xhrProxy.d.ts +0 -9
- package/lib/modules/Network/xhrProxy.js +0 -1
- package/lib/modules/axiosSpy.js +1 -1
- package/lib/modules/constructedStyleSheets.js +25 -21
- package/lib/modules/featureFlags.js +0 -1
- package/lib/modules/img.js +3 -3
- package/lib/modules/network.js +3 -2
- package/lib/utils.d.ts +16 -0
- package/lib/utils.js +47 -0
- package/package.json +13 -13
- package/rollup.config.js +4 -4
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
18
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# 10.0.0
|
|
2
|
+
|
|
3
|
+
- networkRequest message changed to include `TransferredBodySize`
|
|
4
|
+
- tracker now attempts to create proxy for beacon api as well (if its in scope)
|
|
5
|
+
- safe wrapper for angular apps
|
|
6
|
+
- better browser lag handling
|
|
7
|
+
|
|
1
8
|
# 9.0.11
|
|
2
9
|
|
|
3
10
|
- new `resetTabOnWindowOpen` option to fix window.open issue with sessionStorage being inherited (replicating tabId bug), users still should use 'noopener=true' in window.open to prevent it in general...
|
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
The main package of the [OpenReplay](https://openreplay.com/) tracker.
|
|
4
4
|
|
|
5
|
+
## Development & Contribution
|
|
6
|
+
|
|
7
|
+
Please use [bun](https://bun.sh/) to install and build this library. Any submitted pull request must pass **all tests** and should have positive test coverage diff %.
|
|
8
|
+
|
|
5
9
|
## Documentation
|
|
6
10
|
|
|
7
11
|
For launch options and available public methods, [refer to the documentation](https://docs.openreplay.com/installation/javascript-sdk#options)
|
package/bun.lockb
ADDED
|
Binary file
|
package/cjs/app/index.js
CHANGED
|
@@ -39,7 +39,7 @@ class App {
|
|
|
39
39
|
this.stopCallbacks = [];
|
|
40
40
|
this.commitCallbacks = [];
|
|
41
41
|
this.activityState = ActivityState.NotActive;
|
|
42
|
-
this.version = '
|
|
42
|
+
this.version = '10.0.0'; // TODO: version compatability check inside each plugin.
|
|
43
43
|
this.compressionThreshold = 24 * 1000;
|
|
44
44
|
this.restartAttempts = 0;
|
|
45
45
|
this.bc = null;
|
|
@@ -98,7 +98,7 @@ class App {
|
|
|
98
98
|
this.session.applySessionHash(sessionToken);
|
|
99
99
|
}
|
|
100
100
|
try {
|
|
101
|
-
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";class t{constructor(t,i,s,e=10,n=1e3,r){this.onUnauthorised=i,this.onFailure=s,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i",this.isCompressing=void 0!==r}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){this.busy||!this.token?this.queue.push(t):(this.busy=!0,this.isCompressing&&this.onCompress?this.onCompress(t):this.sendBatch(t))}sendNext(){const t=this.queue.shift();t?(this.busy=!0,this.isCompressing&&this.onCompress?this.onCompress(t):this.sendBatch(t)):this.busy=!1}retry(t,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout(()=>this.sendBatch(t,i),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,i){this.busy=!0;const s={Authorization:"Bearer "+this.token};i&&(s["Content-Encoding"]="gzip"),null!==this.token?fetch(this.ingestURL,{body:t,method:"POST",headers:s,keepalive:t.length<65536}).then(s=>{if(401===s.status)return this.busy=!1,void this.onUnauthorised();s.status>=400?this.retry(t,i):(this.attemptsCount=0,this.sendNext())}).catch(s=>{console.warn("OpenReplay:",s),this.retry(t,i)}):setTimeout(()=>{this.sendBatch(t,i)},500)}sendCompressed(t){this.sendBatch(t,!0)}sendUncompressed(t){this.sendBatch(t,!1)}clean(){this.sendNext(),setTimeout(()=>{this.token=null,this.queue.length=0},10)}}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}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(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 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 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: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 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 50:return this.uint(t[1])&&this.string(t[2]);case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);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 57:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58: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 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]);case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 79:return this.string(t[1])&&this.string(t[2]);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 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 114:case 115:return this.uint(t[1]);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 117:case 118:return this.string(t[1])}}}class e{constructor(t,i,e,n,r){this.pageNo=t,this.timestamp=i,this.url=e,this.onBatch=n,this.tabId=r,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){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=null,u=n.NotActive;function a(){h&&h.finaliseBatch()}function o(){u=n.Stopping,null!==p&&(clearInterval(p),p=null),h&&(h.clean(),h=null),r&&(r.clean(),setTimeout(()=>{r=null},20)),setTimeout(()=>{u=n.NotActive},100)}function c(){u!==n.Stopped&&(postMessage("restart"),o())}let g,p=null;self.onmessage=({data:i})=>{if(null!=i){if("stop"===i)return a(),o(),u=n.Stopped;if("forceFlushBatch"!==i){if(!Array.isArray(i)){if("compressed"===i.type){if(!r)return console.debug("WebWorker: sender not initialised. Compressed batch."),void c();r.sendCompressed(i.batch)}if("uncompressed"===i.type){if(!r)return console.debug("WebWorker: sender not initialised. Uncompressed batch."),void c();r.sendUncompressed(i.batch)}return"start"===i.type?(u=n.Starting,r=new t(i.ingestPoint,()=>{c()},t=>{!function(t){postMessage({type:"failure",reason:t}),o()}(t)},i.connAttemptCount,i.connAttemptGap,t=>{postMessage({type:"compress",batch:t},[t.buffer])}),h=new e(i.pageNo,i.timestamp,i.url,t=>r&&r.push(t),i.tabId),null===p&&(p=setInterval(a,1e4)),u=n.Active):"auth"===i.type?r?h?(r.authorise(i.token),void(i.beaconSizeLimit&&h.setBeaconSizeLimit(i.beaconSizeLimit))):(console.debug("WebWorker: writer not initialised. Received auth."),void c()):(console.debug("WebWorker: sender not initialised. Received auth."),void c()):void 0}if(null!==h){const t=h;i.forEach(i=>{55===i[0]&&(i[1]?g=setTimeout(()=>c(),18e5):clearTimeout(g)),t.writeMessage(i)})}h||(postMessage("not_init"),c())}else a()}else a()};'], { type: 'text/javascript' })));
|
|
101
|
+
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";class t{constructor(t,s,i,e=10,n=1e3,h){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.ingestURL=t+"/v1/web/i",this.isCompressing=void 0!==h}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){this.busy||!this.token?this.queue.push(t):(this.busy=!0,this.isCompressing&&this.onCompress?this.onCompress(t):this.sendBatch(t))}sendNext(){const t=this.queue.shift();t?(this.busy=!0,this.isCompressing&&this.onCompress?this.onCompress(t):this.sendBatch(t)):this.busy=!1}retry(t,s){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s){this.busy=!0;const i={Authorization:`Bearer ${this.token}`};s&&(i["Content-Encoding"]="gzip"),null!==this.token?fetch(this.ingestURL,{body:t,method:"POST",headers:i,keepalive:t.length<65536}).then((i=>{if(401===i.status)return this.busy=!1,void this.onUnauthorised();i.status>=400?this.retry(t,s):(this.attemptsCount=0,this.sendNext())})).catch((i=>{console.warn("OpenReplay:",i),this.retry(t,s)})):setTimeout((()=>{this.sendBatch(t,s)}),500)}sendCompressed(t){this.sendBatch(t,!0)}sendUncompressed(t){this.sendBatch(t,!1)}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: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 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])}}}class n{constructor(t,s,i,n,h){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,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){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(){u=h.Stopping,null!==d&&(clearInterval(d),d=null),a&&(a.clean(),a=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{u=h.NotActive}),100)}function p(){u!==h.Stopped&&(postMessage("restart"),c())}let f,d=null;self.onmessage=({data:s})=>{if(null!=s){if("stop"===s)return o(),c(),u=h.Stopped;if("forceFlushBatch"!==s){if(!Array.isArray(s)){if("compressed"===s.type){if(!r)return console.debug("WebWorker: sender not initialised. Compressed batch."),void p();r.sendCompressed(s.batch)}if("uncompressed"===s.type){if(!r)return console.debug("WebWorker: sender not initialised. Uncompressed batch."),void p();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])})),a=new n(s.pageNo,s.timestamp,s.url,(t=>r&&r.push(t)),s.tabId),null===d&&(d=setInterval(o,1e4)),u=h.Active):"auth"===s.type?r?a?(r.authorise(s.token),void(s.beaconSizeLimit&&a.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug("WebWorker: writer not initialised. Received auth."),void p()):(console.debug("WebWorker: sender not initialised. Received auth."),void p()):void 0}if(null!==a){const t=a;s.forEach((s=>{55===s[0]&&(s[1]?f=setTimeout((()=>p()),18e5):clearTimeout(f)),t.writeMessage(s)}))}a||(postMessage("not_init"),p())}else o()}else o()};'], { type: 'text/javascript' })));
|
|
102
102
|
this.worker.onerror = (e) => {
|
|
103
103
|
this._debug('webworker_error', e);
|
|
104
104
|
};
|
|
@@ -220,7 +220,7 @@ class App {
|
|
|
220
220
|
(0, utils_js_1.deprecationWarn)('Fetch plugin', "'network' init option", '/installation/network-options');
|
|
221
221
|
(0, utils_js_1.deprecationWarn)('Axios plugin', "'network' init option", '/installation/network-options');
|
|
222
222
|
}
|
|
223
|
-
if (this._usingOldFetchPlugin && message[0] ===
|
|
223
|
+
if (this._usingOldFetchPlugin && message[0] === 83 /* MType.NetworkRequest */) {
|
|
224
224
|
return;
|
|
225
225
|
}
|
|
226
226
|
// ====================================================
|
|
@@ -235,12 +235,15 @@ class App {
|
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
commit() {
|
|
238
|
-
if (this.worker && this.messages.length) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
238
|
+
if (this.worker !== undefined && this.messages.length) {
|
|
239
|
+
(0, utils_js_1.requestIdleCb)(() => {
|
|
240
|
+
this.messages.unshift((0, messages_gen_js_1.TabData)(this.session.getTabId()));
|
|
241
|
+
this.messages.unshift((0, messages_gen_js_1.Timestamp)(this.timestamp()));
|
|
242
|
+
// ? why I need to do this?
|
|
243
|
+
this.worker.postMessage(this.messages);
|
|
244
|
+
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
245
|
+
this.messages.length = 0;
|
|
246
|
+
});
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
249
|
timestamp() {
|
|
@@ -281,8 +284,8 @@ class App {
|
|
|
281
284
|
if (useSafe) {
|
|
282
285
|
listener = this.safe(listener);
|
|
283
286
|
}
|
|
284
|
-
this.attachStartCallback(() => target
|
|
285
|
-
this.attachStopCallback(() => target
|
|
287
|
+
this.attachStartCallback(() => (target ? (0, utils_js_1.createEventListener)(target, type, listener, useCapture) : null), useSafe);
|
|
288
|
+
this.attachStopCallback(() => (target ? (0, utils_js_1.deleteEventListener)(target, type, listener, useCapture) : null), useSafe);
|
|
286
289
|
}
|
|
287
290
|
// TODO: full correct semantic
|
|
288
291
|
checkRequiredVersion(version) {
|
package/cjs/app/logger.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare function SetInputTarget(id: number, label: string): Messages.SetI
|
|
|
17
17
|
export declare function SetInputValue(id: number, value: string, mask: number): Messages.SetInputValue;
|
|
18
18
|
export declare function SetInputChecked(id: number, checked: boolean): Messages.SetInputChecked;
|
|
19
19
|
export declare function MouseMove(x: number, y: number): Messages.MouseMove;
|
|
20
|
-
export declare function
|
|
20
|
+
export declare function NetworkRequestDeprecated(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number): Messages.NetworkRequestDeprecated;
|
|
21
21
|
export declare function ConsoleLog(level: string, value: string): Messages.ConsoleLog;
|
|
22
22
|
export declare function PageLoadTiming(requestStart: number, responseStart: number, responseEnd: number, domContentLoadedEventStart: number, domContentLoadedEventEnd: number, loadEventStart: number, loadEventEnd: number, firstPaint: number, firstContentfulPaint: number): Messages.PageLoadTiming;
|
|
23
23
|
export declare function PageRenderTiming(speedIndex: number, visuallyComplete: number, timeToInteractive: number): Messages.PageRenderTiming;
|
|
@@ -61,6 +61,7 @@ export declare function JSException(name: string, message: string, payload: stri
|
|
|
61
61
|
export declare function Zustand(mutation: string, state: string): Messages.Zustand;
|
|
62
62
|
export declare function BatchMetadata(version: number, pageNo: number, firstIndex: number, timestamp: number, location: string): Messages.BatchMetadata;
|
|
63
63
|
export declare function PartitionedMessage(partNo: number, partTotal: number): Messages.PartitionedMessage;
|
|
64
|
+
export declare function NetworkRequest(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number, transferredBodySize: number): Messages.NetworkRequest;
|
|
64
65
|
export declare function InputChange(id: number, value: string, valueMasked: boolean, label: string, hesitationTime: number, inputDuration: number): Messages.InputChange;
|
|
65
66
|
export declare function SelectionChange(selectionStart: number, selectionEnd: number, selection: string): Messages.SelectionChange;
|
|
66
67
|
export declare function MouseThrashing(timestamp: number): Messages.MouseThrashing;
|
package/cjs/app/messages.gen.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Auto-generated, do not edit
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.CSSInsertRuleURLBased = exports.CustomIssue = exports.TechnicalInfo = exports.SetCSSDataURLBased = exports.SetNodeAttributeURLBased = exports.LongTask = exports.SetNodeFocus = exports.LoadFontFace = exports.SetPageVisibility = exports.ConnectionInformation = exports.ResourceTimingDeprecated = exports.SetNodeAttributeDict = exports.StringDict = exports.PerformanceTrack = exports.GraphQL = exports.NgRx = exports.MobX = exports.Vuex = exports.Redux = exports.StateAction = exports.OTable = exports.Profiler = exports.Fetch = exports.CSSDeleteRule = exports.CSSInsertRule = exports.Metadata = exports.UserAnonymousID = exports.UserID = exports.CustomEvent = exports.PageRenderTiming = exports.PageLoadTiming = exports.ConsoleLog = exports.
|
|
6
|
-
exports.TabData = exports.TabChange = exports.ResourceTiming = exports.UnbindNodes = exports.MouseThrashing = exports.SelectionChange = exports.InputChange = exports.PartitionedMessage = exports.BatchMetadata = exports.Zustand = exports.JSException = exports.AdoptedSSRemoveOwner = exports.AdoptedSSAddOwner = exports.AdoptedSSDeleteRule = exports.AdoptedSSInsertRuleURLBased = exports.AdoptedSSReplaceURLBased = exports.CreateIFrameDocument = exports.MouseClick = void 0;
|
|
5
|
+
exports.CSSInsertRuleURLBased = exports.CustomIssue = exports.TechnicalInfo = exports.SetCSSDataURLBased = exports.SetNodeAttributeURLBased = exports.LongTask = exports.SetNodeFocus = exports.LoadFontFace = exports.SetPageVisibility = exports.ConnectionInformation = exports.ResourceTimingDeprecated = exports.SetNodeAttributeDict = exports.StringDict = exports.PerformanceTrack = exports.GraphQL = exports.NgRx = exports.MobX = exports.Vuex = exports.Redux = exports.StateAction = exports.OTable = exports.Profiler = exports.Fetch = exports.CSSDeleteRule = exports.CSSInsertRule = exports.Metadata = exports.UserAnonymousID = exports.UserID = exports.CustomEvent = exports.PageRenderTiming = exports.PageLoadTiming = exports.ConsoleLog = exports.NetworkRequestDeprecated = exports.MouseMove = exports.SetInputChecked = exports.SetInputValue = exports.SetInputTarget = exports.SetNodeScroll = exports.SetNodeData = exports.RemoveNodeAttribute = exports.SetNodeAttribute = exports.RemoveNode = exports.MoveNode = exports.CreateTextNode = exports.CreateElementNode = exports.CreateDocument = exports.SetViewportScroll = exports.SetViewportSize = exports.SetPageLocation = exports.Timestamp = void 0;
|
|
6
|
+
exports.TabData = exports.TabChange = exports.ResourceTiming = exports.UnbindNodes = exports.MouseThrashing = exports.SelectionChange = exports.InputChange = exports.NetworkRequest = exports.PartitionedMessage = exports.BatchMetadata = exports.Zustand = exports.JSException = exports.AdoptedSSRemoveOwner = exports.AdoptedSSAddOwner = exports.AdoptedSSDeleteRule = exports.AdoptedSSInsertRuleURLBased = exports.AdoptedSSReplaceURLBased = exports.CreateIFrameDocument = exports.MouseClick = void 0;
|
|
7
7
|
function Timestamp(timestamp) {
|
|
8
8
|
return [
|
|
9
9
|
0 /* Messages.Type.Timestamp */,
|
|
@@ -145,9 +145,9 @@ function MouseMove(x, y) {
|
|
|
145
145
|
];
|
|
146
146
|
}
|
|
147
147
|
exports.MouseMove = MouseMove;
|
|
148
|
-
function
|
|
148
|
+
function NetworkRequestDeprecated(type, method, url, request, response, status, timestamp, duration) {
|
|
149
149
|
return [
|
|
150
|
-
21 /* Messages.Type.
|
|
150
|
+
21 /* Messages.Type.NetworkRequestDeprecated */,
|
|
151
151
|
type,
|
|
152
152
|
method,
|
|
153
153
|
url,
|
|
@@ -158,7 +158,7 @@ function NetworkRequest(type, method, url, request, response, status, timestamp,
|
|
|
158
158
|
duration,
|
|
159
159
|
];
|
|
160
160
|
}
|
|
161
|
-
exports.
|
|
161
|
+
exports.NetworkRequestDeprecated = NetworkRequestDeprecated;
|
|
162
162
|
function ConsoleLog(level, value) {
|
|
163
163
|
return [
|
|
164
164
|
22 /* Messages.Type.ConsoleLog */,
|
|
@@ -549,6 +549,21 @@ function PartitionedMessage(partNo, partTotal) {
|
|
|
549
549
|
];
|
|
550
550
|
}
|
|
551
551
|
exports.PartitionedMessage = PartitionedMessage;
|
|
552
|
+
function NetworkRequest(type, method, url, request, response, status, timestamp, duration, transferredBodySize) {
|
|
553
|
+
return [
|
|
554
|
+
83 /* Messages.Type.NetworkRequest */,
|
|
555
|
+
type,
|
|
556
|
+
method,
|
|
557
|
+
url,
|
|
558
|
+
request,
|
|
559
|
+
response,
|
|
560
|
+
status,
|
|
561
|
+
timestamp,
|
|
562
|
+
duration,
|
|
563
|
+
transferredBodySize,
|
|
564
|
+
];
|
|
565
|
+
}
|
|
566
|
+
exports.NetworkRequest = NetworkRequest;
|
|
552
567
|
function InputChange(id, value, valueMasked, label, hesitationTime, inputDuration) {
|
|
553
568
|
return [
|
|
554
569
|
112 /* Messages.Type.InputChange */,
|
package/cjs/app/nodes.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_js_1 = require("../utils.js");
|
|
3
4
|
class Nodes {
|
|
4
5
|
constructor(node_id) {
|
|
5
6
|
this.node_id = node_id;
|
|
@@ -17,7 +18,7 @@ class Nodes {
|
|
|
17
18
|
if (id === undefined) {
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
(0, utils_js_1.createEventListener)(node, type, listener, useCapture);
|
|
21
22
|
let listeners = this.elementListeners.get(id);
|
|
22
23
|
if (listeners === undefined) {
|
|
23
24
|
listeners = [];
|
|
@@ -44,7 +45,7 @@ class Nodes {
|
|
|
44
45
|
const listeners = this.elementListeners.get(id);
|
|
45
46
|
if (listeners !== undefined) {
|
|
46
47
|
this.elementListeners.delete(id);
|
|
47
|
-
listeners.forEach((listener) =>
|
|
48
|
+
listeners.forEach((listener) => (0, utils_js_1.deleteEventListener)(node, listener[0], listener[1], listener[2]));
|
|
48
49
|
}
|
|
49
50
|
this.totalNodeAmount--;
|
|
50
51
|
}
|
|
@@ -79,7 +80,7 @@ class Nodes {
|
|
|
79
80
|
clear() {
|
|
80
81
|
for (let id = 0; id < this.nodes.length; id++) {
|
|
81
82
|
const node = this.nodes[id];
|
|
82
|
-
if (node
|
|
83
|
+
if (!node) {
|
|
83
84
|
continue;
|
|
84
85
|
}
|
|
85
86
|
this.unregisterNode(node);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_js_1 = require("../../utils.js");
|
|
3
4
|
const messages_gen_js_1 = require("../messages.gen.js");
|
|
4
5
|
const guards_js_1 = require("../guards.js");
|
|
5
6
|
function isIgnored(node) {
|
|
@@ -46,7 +47,7 @@ class Observer {
|
|
|
46
47
|
this.indexes = [];
|
|
47
48
|
this.attributesMap = new Map();
|
|
48
49
|
this.textSet = new Set();
|
|
49
|
-
this.observer =
|
|
50
|
+
this.observer = (0, utils_js_1.createMutationObserver)(this.app.safe((mutations) => {
|
|
50
51
|
for (const mutation of mutations) {
|
|
51
52
|
// mutations order is sequential
|
|
52
53
|
const target = mutation.target;
|
|
@@ -16,7 +16,7 @@ export declare const enum Type {
|
|
|
16
16
|
SetInputValue = 18,
|
|
17
17
|
SetInputChecked = 19,
|
|
18
18
|
MouseMove = 20,
|
|
19
|
-
|
|
19
|
+
NetworkRequestDeprecated = 21,
|
|
20
20
|
ConsoleLog = 22,
|
|
21
21
|
PageLoadTiming = 23,
|
|
22
22
|
PageRenderTiming = 24,
|
|
@@ -60,6 +60,7 @@ export declare const enum Type {
|
|
|
60
60
|
Zustand = 79,
|
|
61
61
|
BatchMetadata = 81,
|
|
62
62
|
PartitionedMessage = 82,
|
|
63
|
+
NetworkRequest = 83,
|
|
63
64
|
InputChange = 112,
|
|
64
65
|
SelectionChange = 113,
|
|
65
66
|
MouseThrashing = 114,
|
|
@@ -158,8 +159,8 @@ export type MouseMove = [
|
|
|
158
159
|
number,
|
|
159
160
|
number
|
|
160
161
|
];
|
|
161
|
-
export type
|
|
162
|
-
Type.
|
|
162
|
+
export type NetworkRequestDeprecated = [
|
|
163
|
+
Type.NetworkRequestDeprecated,
|
|
163
164
|
string,
|
|
164
165
|
string,
|
|
165
166
|
string,
|
|
@@ -430,6 +431,18 @@ export type PartitionedMessage = [
|
|
|
430
431
|
number,
|
|
431
432
|
number
|
|
432
433
|
];
|
|
434
|
+
export type NetworkRequest = [
|
|
435
|
+
Type.NetworkRequest,
|
|
436
|
+
string,
|
|
437
|
+
string,
|
|
438
|
+
string,
|
|
439
|
+
string,
|
|
440
|
+
string,
|
|
441
|
+
number,
|
|
442
|
+
number,
|
|
443
|
+
number,
|
|
444
|
+
number
|
|
445
|
+
];
|
|
433
446
|
export type InputChange = [
|
|
434
447
|
Type.InputChange,
|
|
435
448
|
number,
|
|
@@ -474,5 +487,5 @@ export type TabData = [
|
|
|
474
487
|
Type.TabData,
|
|
475
488
|
string
|
|
476
489
|
];
|
|
477
|
-
type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove |
|
|
490
|
+
type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData;
|
|
478
491
|
export default Message;
|
package/cjs/index.js
CHANGED
|
@@ -162,7 +162,7 @@ class API {
|
|
|
162
162
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
163
163
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
164
164
|
req.send(JSON.stringify({
|
|
165
|
-
trackerVersion: '
|
|
165
|
+
trackerVersion: '10.0.0',
|
|
166
166
|
projectKey: options.projectKey,
|
|
167
167
|
doNotTrack,
|
|
168
168
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NetworkRequest } from '../../common/messages.gen.js';
|
|
2
|
+
import { RequestResponseData } from './types.js';
|
|
3
|
+
export declare class BeaconProxyHandler<T extends typeof navigator.sendBeacon> implements ProxyHandler<T> {
|
|
4
|
+
private readonly ignoredHeaders;
|
|
5
|
+
private readonly setSessionTokenHeader;
|
|
6
|
+
private readonly sanitize;
|
|
7
|
+
private readonly sendMessage;
|
|
8
|
+
private readonly isServiceUrl;
|
|
9
|
+
constructor(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean);
|
|
10
|
+
apply(target: T, thisArg: T, argsList: any[]): any;
|
|
11
|
+
}
|
|
12
|
+
export default class BeaconProxy {
|
|
13
|
+
static origSendBeacon: (url: string | URL, data?: BodyInit | null | undefined) => boolean;
|
|
14
|
+
static hasSendBeacon(): boolean;
|
|
15
|
+
static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): any;
|
|
16
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.BeaconProxyHandler = void 0;
|
|
5
|
+
const networkMessage_js_1 = require("./networkMessage.js");
|
|
6
|
+
const utils_js_1 = require("./utils.js");
|
|
7
|
+
// https://fetch.spec.whatwg.org/#concept-bodyinit-extract
|
|
8
|
+
const getContentType = (data) => {
|
|
9
|
+
if (data instanceof Blob) {
|
|
10
|
+
return data.type;
|
|
11
|
+
}
|
|
12
|
+
if (data instanceof FormData) {
|
|
13
|
+
return 'multipart/form-data';
|
|
14
|
+
}
|
|
15
|
+
if (data instanceof URLSearchParams) {
|
|
16
|
+
return 'application/x-www-form-urlencoded;charset=UTF-8';
|
|
17
|
+
}
|
|
18
|
+
return 'text/plain;charset=UTF-8';
|
|
19
|
+
};
|
|
20
|
+
class BeaconProxyHandler {
|
|
21
|
+
constructor(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
|
|
22
|
+
this.ignoredHeaders = ignoredHeaders;
|
|
23
|
+
this.setSessionTokenHeader = setSessionTokenHeader;
|
|
24
|
+
this.sanitize = sanitize;
|
|
25
|
+
this.sendMessage = sendMessage;
|
|
26
|
+
this.isServiceUrl = isServiceUrl;
|
|
27
|
+
}
|
|
28
|
+
apply(target, thisArg, argsList) {
|
|
29
|
+
const urlString = argsList[0];
|
|
30
|
+
const data = argsList[1];
|
|
31
|
+
const item = new networkMessage_js_1.default(this.ignoredHeaders, this.setSessionTokenHeader, this.sanitize);
|
|
32
|
+
if (this.isServiceUrl(urlString)) {
|
|
33
|
+
return target.apply(thisArg, argsList);
|
|
34
|
+
}
|
|
35
|
+
const url = (0, utils_js_1.getURL)(urlString);
|
|
36
|
+
item.method = 'POST';
|
|
37
|
+
item.url = urlString;
|
|
38
|
+
item.name = (url.pathname.split('/').pop() || '') + url.search;
|
|
39
|
+
item.requestType = 'beacon';
|
|
40
|
+
item.requestHeader = { 'Content-Type': getContentType(data) };
|
|
41
|
+
item.status = 0;
|
|
42
|
+
item.statusText = 'Pending';
|
|
43
|
+
if (url.search && url.searchParams) {
|
|
44
|
+
item.getData = {};
|
|
45
|
+
for (const [key, value] of url.searchParams) {
|
|
46
|
+
item.getData[key] = value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
item.requestData = (0, utils_js_1.genStringBody)(data);
|
|
50
|
+
if (!item.startTime) {
|
|
51
|
+
item.startTime = performance.now();
|
|
52
|
+
}
|
|
53
|
+
const isSuccess = target.apply(thisArg, argsList);
|
|
54
|
+
if (isSuccess) {
|
|
55
|
+
item.endTime = performance.now();
|
|
56
|
+
item.duration = item.endTime - (item.startTime || item.endTime);
|
|
57
|
+
item.status = 0;
|
|
58
|
+
item.statusText = 'Sent';
|
|
59
|
+
item.readyState = 4;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
item.status = 500;
|
|
63
|
+
item.statusText = 'Unknown';
|
|
64
|
+
}
|
|
65
|
+
this.sendMessage(item.getMessage());
|
|
66
|
+
return isSuccess;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.BeaconProxyHandler = BeaconProxyHandler;
|
|
70
|
+
class BeaconProxy {
|
|
71
|
+
static hasSendBeacon() {
|
|
72
|
+
return !!BeaconProxy.origSendBeacon;
|
|
73
|
+
}
|
|
74
|
+
static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
|
|
75
|
+
if (!BeaconProxy.hasSendBeacon()) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
return new Proxy(BeaconProxy.origSendBeacon, new BeaconProxyHandler(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.default = BeaconProxy;
|
|
82
|
+
BeaconProxy.origSendBeacon = (_a = window === null || window === void 0 ? void 0 : window.navigator) === null || _a === void 0 ? void 0 : _a.sendBeacon;
|
|
@@ -30,6 +30,5 @@ export declare class FetchProxyHandler<T extends typeof fetch> implements ProxyH
|
|
|
30
30
|
protected handleResponseBody(resp: Response, item: NetworkMessage): Promise<ArrayBuffer> | Promise<string>;
|
|
31
31
|
}
|
|
32
32
|
export default class FetchProxy {
|
|
33
|
-
static origFetch: typeof fetch;
|
|
34
33
|
static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): typeof fetch;
|
|
35
34
|
}
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const fetchProxy_js_1 = require("./fetchProxy.js");
|
|
4
4
|
const xhrProxy_js_1 = require("./xhrProxy.js");
|
|
5
|
+
const beaconProxy_js_1 = require("./beaconProxy.js");
|
|
5
6
|
const getWarning = (api) => console.warn(`Openreplay: Can't find ${api} in global context.
|
|
6
7
|
If you're using serverside rendering in your app, make sure that tracker is loaded dynamically, otherwise ${api} won't be tracked.`);
|
|
7
8
|
function setProxy(context, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
|
|
9
|
+
var _a;
|
|
8
10
|
if (context.XMLHttpRequest) {
|
|
9
11
|
context.XMLHttpRequest = xhrProxy_js_1.default.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher);
|
|
10
12
|
}
|
|
@@ -17,5 +19,8 @@ function setProxy(context, ignoredHeaders, setSessionTokenHeader, sanitize, send
|
|
|
17
19
|
else {
|
|
18
20
|
getWarning('fetch');
|
|
19
21
|
}
|
|
22
|
+
if ((_a = context === null || context === void 0 ? void 0 : context.navigator) === null || _a === void 0 ? void 0 : _a.sendBeacon) {
|
|
23
|
+
context.navigator.sendBeacon = beaconProxy_js_1.default.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl);
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
26
|
exports.default = setProxy;
|
|
@@ -27,7 +27,7 @@ export default class NetworkMessage {
|
|
|
27
27
|
[key: string]: string;
|
|
28
28
|
};
|
|
29
29
|
responseType: XMLHttpRequest['responseType'];
|
|
30
|
-
requestType: 'xhr' | 'fetch' | 'ping' | 'custom';
|
|
30
|
+
requestType: 'xhr' | 'fetch' | 'ping' | 'custom' | 'beacon';
|
|
31
31
|
requestHeader: HeadersInit;
|
|
32
32
|
response: any;
|
|
33
33
|
responseSize: number;
|
|
@@ -53,7 +53,7 @@ class NetworkMessage {
|
|
|
53
53
|
request,
|
|
54
54
|
response,
|
|
55
55
|
});
|
|
56
|
-
return (0, messages_gen_js_1.NetworkRequest)(this.requestType, messageInfo.method, messageInfo.url, JSON.stringify(messageInfo.request), JSON.stringify(messageInfo.response), messageInfo.status, this.startTime + (0, utils_js_1.getTimeOrigin)(), this.duration);
|
|
56
|
+
return (0, messages_gen_js_1.NetworkRequest)(this.requestType, messageInfo.method, messageInfo.url, JSON.stringify(messageInfo.request), JSON.stringify(messageInfo.response), messageInfo.status, this.startTime + (0, utils_js_1.getTimeOrigin)(), this.duration, this.responseSize);
|
|
57
57
|
}
|
|
58
58
|
writeHeaders() {
|
|
59
59
|
const reqHs = {};
|
|
@@ -35,14 +35,5 @@ export declare class XHRProxyHandler<T extends XMLHttpRequest> implements ProxyH
|
|
|
35
35
|
protected updateItemByReadyState(): void;
|
|
36
36
|
}
|
|
37
37
|
export default class XHRProxy {
|
|
38
|
-
static origXMLHttpRequest: {
|
|
39
|
-
new (): XMLHttpRequest;
|
|
40
|
-
prototype: XMLHttpRequest;
|
|
41
|
-
readonly DONE: number;
|
|
42
|
-
readonly HEADERS_RECEIVED: number;
|
|
43
|
-
readonly LOADING: number;
|
|
44
|
-
readonly OPENED: number;
|
|
45
|
-
readonly UNSENT: number;
|
|
46
|
-
};
|
|
47
38
|
static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (data: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): any;
|
|
48
39
|
}
|
package/cjs/modules/axiosSpy.js
CHANGED
|
@@ -67,7 +67,7 @@ function default_1(app, instance, opts, sanitize, stringify) {
|
|
|
67
67
|
const requestStart = axiosResponseObj.config.__openreplay_timing;
|
|
68
68
|
const duration = performance.now() - requestStart;
|
|
69
69
|
app.debug.log('Openreplay: final req object', reqResInfo);
|
|
70
|
-
app.send((0, messages_gen_js_1.NetworkRequest)('xhr', String(method), String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), reqResInfo.status, requestStart + (0, utils_js_1.getTimeOrigin)(), duration));
|
|
70
|
+
app.send((0, messages_gen_js_1.NetworkRequest)('xhr', String(method), String(reqResInfo.url), stringify(reqResInfo.request), stringify(reqResInfo.response), reqResInfo.status, requestStart + (0, utils_js_1.getTimeOrigin)(), duration, 0));
|
|
71
71
|
}
|
|
72
72
|
function getStartTime(config) {
|
|
73
73
|
app.debug.log('Openreplay: capturing API request', config);
|
|
@@ -8,7 +8,7 @@ function hasAdoptedSS(node) {
|
|
|
8
8
|
// @ts-ignore
|
|
9
9
|
!!node.adoptedStyleSheets);
|
|
10
10
|
}
|
|
11
|
-
// TODO:
|
|
11
|
+
// TODO: encapsulate to be init-ed on-start and join with cssrules.ts under one folder
|
|
12
12
|
let _id = 0xf;
|
|
13
13
|
function nextID() {
|
|
14
14
|
return _id++;
|
|
@@ -38,35 +38,39 @@ function default_1(app) {
|
|
|
38
38
|
}
|
|
39
39
|
const nowOwning = [];
|
|
40
40
|
const styleSheets = root.adoptedStyleSheets;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (init) {
|
|
52
|
-
const rules = s.cssRules;
|
|
53
|
-
for (let i = 0; i < rules.length; i++) {
|
|
54
|
-
app.send((0, messages_gen_js_1.AdoptedSSInsertRuleURLBased)(sheetID, rules[i].cssText, i, app.getBaseHref()));
|
|
41
|
+
if (Symbol.iterator in styleSheets) {
|
|
42
|
+
for (const s of styleSheets) {
|
|
43
|
+
let sheetID = styleSheetIDMap.get(s);
|
|
44
|
+
const init = !sheetID;
|
|
45
|
+
if (!sheetID) {
|
|
46
|
+
sheetID = nextID();
|
|
47
|
+
styleSheetIDMap.set(s, sheetID);
|
|
48
|
+
}
|
|
49
|
+
if (!pastOwning.includes(sheetID)) {
|
|
50
|
+
app.send((0, messages_gen_js_1.AdoptedSSAddOwner)(sheetID, nodeID));
|
|
55
51
|
}
|
|
52
|
+
if (init) {
|
|
53
|
+
const rules = s.cssRules;
|
|
54
|
+
for (let i = 0; i < rules.length; i++) {
|
|
55
|
+
app.send((0, messages_gen_js_1.AdoptedSSInsertRuleURLBased)(sheetID, rules[i].cssText, i, app.getBaseHref()));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
nowOwning.push(sheetID);
|
|
56
59
|
}
|
|
57
|
-
nowOwning.push(sheetID);
|
|
58
60
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
if (Symbol.iterator in pastOwning) {
|
|
62
|
+
for (const sheetID of pastOwning) {
|
|
63
|
+
if (!nowOwning.includes(sheetID)) {
|
|
64
|
+
app.send((0, messages_gen_js_1.AdoptedSSRemoveOwner)(sheetID, nodeID));
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
adoptedStyleSheetsOwnings.set(nodeID, nowOwning);
|
|
65
|
-
}, 20); //
|
|
69
|
+
}, 20); // Mysterious bug:
|
|
66
70
|
/* On the page https://explore.fast.design/components/fast-accordion
|
|
67
71
|
the only rule inside the only adoptedStyleSheet of the iframe-s document
|
|
68
72
|
gets changed during first milliseconds after the load.
|
|
69
|
-
|
|
73
|
+
However, none of the documented methods (replace, insertRule) is triggered.
|
|
70
74
|
The rule is not substituted (remains the same object), however the text gets changed.
|
|
71
75
|
*/
|
|
72
76
|
function patchAdoptedStyleSheets(prototype) {
|
package/cjs/modules/img.js
CHANGED
|
@@ -77,7 +77,7 @@ function default_1(app) {
|
|
|
77
77
|
sendSrcset(id, img);
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
|
-
const observer =
|
|
80
|
+
const observer = (0, utils_js_1.createMutationObserver)(app.safe((mutations) => {
|
|
81
81
|
for (const mutation of mutations) {
|
|
82
82
|
if (mutation.type === 'attributes') {
|
|
83
83
|
const target = mutation.target;
|
|
@@ -93,7 +93,7 @@ function default_1(app) {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
});
|
|
96
|
+
}));
|
|
97
97
|
app.attachStopCallback(() => {
|
|
98
98
|
observer.disconnect();
|
|
99
99
|
});
|