@openreplay/tracker 9.0.12 → 10.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/.nvmrc +1 -0
  2. package/CHANGELOG.md +15 -0
  3. package/README.md +4 -0
  4. package/bun.lockb +0 -0
  5. package/cjs/app/index.js +14 -11
  6. package/cjs/app/logger.d.ts +1 -1
  7. package/cjs/app/messages.gen.d.ts +2 -1
  8. package/cjs/app/messages.gen.js +20 -5
  9. package/cjs/app/nodes.js +4 -3
  10. package/cjs/app/observer/observer.js +2 -1
  11. package/cjs/common/messages.gen.d.ts +17 -4
  12. package/cjs/index.js +1 -1
  13. package/cjs/modules/Network/beaconProxy.d.ts +16 -0
  14. package/cjs/modules/Network/beaconProxy.js +82 -0
  15. package/cjs/modules/Network/fetchProxy.d.ts +0 -1
  16. package/cjs/modules/Network/fetchProxy.js +3 -1
  17. package/cjs/modules/Network/index.js +5 -0
  18. package/cjs/modules/Network/networkMessage.d.ts +1 -1
  19. package/cjs/modules/Network/networkMessage.js +7 -4
  20. package/cjs/modules/Network/xhrProxy.d.ts +0 -9
  21. package/cjs/modules/Network/xhrProxy.js +0 -1
  22. package/cjs/modules/axiosSpy.js +1 -1
  23. package/cjs/modules/constructedStyleSheets.js +25 -21
  24. package/cjs/modules/featureFlags.js +0 -1
  25. package/cjs/modules/img.js +2 -2
  26. package/cjs/modules/network.js +5 -4
  27. package/cjs/utils.d.ts +16 -0
  28. package/cjs/utils.js +53 -1
  29. package/coverage/clover.xml +829 -1064
  30. package/coverage/coverage-final.json +17 -21
  31. package/coverage/lcov-report/index.html +40 -55
  32. package/coverage/lcov-report/main/app/guards.ts.html +1 -1
  33. package/coverage/lcov-report/main/app/index.html +23 -23
  34. package/coverage/lcov-report/main/app/index.ts.html +212 -29
  35. package/coverage/lcov-report/main/app/logger.ts.html +2 -2
  36. package/coverage/lcov-report/main/app/messages.gen.ts.html +144 -144
  37. package/coverage/lcov-report/main/app/nodes.ts.html +13 -7
  38. package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
  39. package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
  40. package/coverage/lcov-report/main/app/observer/index.html +1 -1
  41. package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
  42. package/coverage/lcov-report/main/app/observer/top_observer.ts.html +1 -1
  43. package/coverage/lcov-report/main/app/sanitizer.ts.html +12 -3
  44. package/coverage/lcov-report/main/app/session.ts.html +30 -9
  45. package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
  46. package/coverage/lcov-report/main/index.html +21 -21
  47. package/coverage/lcov-report/main/index.ts.html +26 -26
  48. package/coverage/lcov-report/main/modules/Network/beaconProxy.ts.html +19 -19
  49. package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +102 -96
  50. package/coverage/lcov-report/main/modules/Network/index.html +65 -65
  51. package/coverage/lcov-report/main/modules/Network/index.ts.html +33 -33
  52. package/coverage/lcov-report/main/modules/Network/networkMessage.ts.html +71 -71
  53. package/coverage/lcov-report/main/modules/Network/utils.ts.html +34 -34
  54. package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +13 -13
  55. package/coverage/lcov-report/main/modules/attributeSender.ts.html +13 -4
  56. package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
  57. package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
  58. package/coverage/lcov-report/main/modules/console.ts.html +1 -1
  59. package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +42 -30
  60. package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
  61. package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
  62. package/coverage/lcov-report/main/modules/featureFlags.ts.html +1 -1
  63. package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
  64. package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
  65. package/coverage/lcov-report/main/modules/img.ts.html +23 -20
  66. package/coverage/lcov-report/main/modules/index.html +13 -13
  67. package/coverage/lcov-report/main/modules/input.ts.html +1 -1
  68. package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
  69. package/coverage/lcov-report/main/modules/network.ts.html +2 -2
  70. package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
  71. package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
  72. package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
  73. package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
  74. package/coverage/lcov-report/main/modules/timing.ts.html +42 -6
  75. package/coverage/lcov-report/main/modules/viewport.ts.html +1 -1
  76. package/coverage/lcov-report/main/utils.ts.html +255 -39
  77. package/coverage/lcov-report/webworker/BatchWriter.ts.html +1 -1
  78. package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +1 -1
  79. package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +1 -1
  80. package/coverage/lcov-report/webworker/QueueSender.ts.html +1 -1
  81. package/coverage/lcov-report/webworker/index.html +1 -1
  82. package/coverage/lcov-report/webworker/index.ts.html +1 -1
  83. package/coverage/lcov.info +1376 -1729
  84. package/lib/app/index.js +15 -12
  85. package/lib/app/logger.d.ts +1 -1
  86. package/lib/app/messages.gen.d.ts +2 -1
  87. package/lib/app/messages.gen.js +16 -2
  88. package/lib/app/nodes.js +4 -3
  89. package/lib/app/observer/observer.js +2 -1
  90. package/lib/common/messages.gen.d.ts +17 -4
  91. package/lib/common/tsconfig.tsbuildinfo +1 -1
  92. package/lib/index.js +1 -1
  93. package/lib/modules/Network/beaconProxy.d.ts +16 -0
  94. package/lib/modules/Network/beaconProxy.js +77 -0
  95. package/lib/modules/Network/fetchProxy.d.ts +0 -1
  96. package/lib/modules/Network/fetchProxy.js +3 -1
  97. package/lib/modules/Network/index.js +5 -0
  98. package/lib/modules/Network/networkMessage.d.ts +1 -1
  99. package/lib/modules/Network/networkMessage.js +7 -4
  100. package/lib/modules/Network/xhrProxy.d.ts +0 -9
  101. package/lib/modules/Network/xhrProxy.js +0 -1
  102. package/lib/modules/axiosSpy.js +1 -1
  103. package/lib/modules/constructedStyleSheets.js +25 -21
  104. package/lib/modules/featureFlags.js +0 -1
  105. package/lib/modules/img.js +3 -3
  106. package/lib/modules/network.js +5 -4
  107. package/lib/utils.d.ts +16 -0
  108. package/lib/utils.js +47 -0
  109. package/package.json +13 -13
  110. package/rollup.config.js +4 -4
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 18
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # 10.0.2
2
+
3
+ - fix default ignore headers
4
+
5
+ # 10.0.1
6
+
7
+ - network proxy api is now default turned on
8
+
9
+ # 10.0.0
10
+
11
+ - networkRequest message changed to include `TransferredBodySize`
12
+ - tracker now attempts to create proxy for beacon api as well (if its in scope of the current env)
13
+ - safe wrapper for angular apps
14
+ - better browser lag handling (and some performance improvements as a bonus)
15
+
1
16
  # 9.0.11
2
17
 
3
18
  - 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 = '9.0.12'; // TODO: version compatability check inside each plugin.
42
+ this.version = '10.0.2'; // 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] === 21 /* MType.NetworkRequest */) {
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
- this.messages.unshift((0, messages_gen_js_1.TabData)(this.session.getTabId()));
240
- this.messages.unshift((0, messages_gen_js_1.Timestamp)(this.timestamp()));
241
- this.worker.postMessage(this.messages);
242
- this.commitCallbacks.forEach((cb) => cb(this.messages));
243
- this.messages.length = 0;
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 === null || target === void 0 ? void 0 : target.addEventListener(type, listener, useCapture), useSafe);
285
- this.attachStopCallback(() => target === null || target === void 0 ? void 0 : target.removeEventListener(type, listener, useCapture), useSafe);
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) {
@@ -5,7 +5,7 @@ export declare const LogLevel: {
5
5
  readonly Errors: 2;
6
6
  readonly Silent: 0;
7
7
  };
8
- type LogLevel = typeof LogLevel[keyof typeof LogLevel];
8
+ type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];
9
9
  type CustomLevel = {
10
10
  error: boolean;
11
11
  warn: boolean;
@@ -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 NetworkRequest(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number): Messages.NetworkRequest;
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;
@@ -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.NetworkRequest = 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.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 NetworkRequest(type, method, url, request, response, status, timestamp, duration) {
148
+ function NetworkRequestDeprecated(type, method, url, request, response, status, timestamp, duration) {
149
149
  return [
150
- 21 /* Messages.Type.NetworkRequest */,
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.NetworkRequest = NetworkRequest;
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
- node.addEventListener(type, listener, useCapture);
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) => node.removeEventListener(listener[0], listener[1], listener[2]));
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 === undefined) {
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 = new MutationObserver(this.app.safe((mutations) => {
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
- NetworkRequest = 21,
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 NetworkRequest = [
162
- Type.NetworkRequest,
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 | NetworkRequest | 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 | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData;
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: '9.0.12',
165
+ trackerVersion: '10.0.2',
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
  }
@@ -117,6 +117,9 @@ class FetchProxyHandler {
117
117
  apply(target, _, argsList) {
118
118
  const input = argsList[0];
119
119
  const init = argsList[1];
120
+ // @ts-ignore
121
+ if (!(input === null || input === void 0 ? void 0 : input.url) && !input)
122
+ return target.apply(window, argsList);
120
123
  const isORUrl = input instanceof URL || typeof input === 'string'
121
124
  ? this.isServiceUrl(String(input))
122
125
  : this.isServiceUrl(String(input.url));
@@ -267,4 +270,3 @@ class FetchProxy {
267
270
  }
268
271
  }
269
272
  exports.default = FetchProxy;
270
- FetchProxy.origFetch = fetch;
@@ -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 = {};
@@ -74,9 +74,12 @@ class NetworkMessage {
74
74
  return { reqHs, resHs };
75
75
  }
76
76
  isHeaderIgnored(key) {
77
- if (Array.isArray(this.ignoredHeaders))
78
- return this.ignoredHeaders.includes(key);
79
- return this.ignoredHeaders;
77
+ if (Array.isArray(this.ignoredHeaders)) {
78
+ return this.ignoredHeaders.map((k) => k.toLowerCase()).includes(key.toLowerCase());
79
+ }
80
+ else {
81
+ return this.ignoredHeaders;
82
+ }
80
83
  }
81
84
  }
82
85
  exports.default = NetworkMessage;
@@ -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
  }
@@ -215,4 +215,3 @@ class XHRProxy {
215
215
  }
216
216
  }
217
217
  exports.default = XHRProxy;
218
- XHRProxy.origXMLHttpRequest = XMLHttpRequest;
@@ -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: incapsulate to be init-ed on-start and join with cssrules.ts under one folder
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
- for (const s of styleSheets) {
42
- let sheetID = styleSheetIDMap.get(s);
43
- const init = !sheetID;
44
- if (!sheetID) {
45
- sheetID = nextID();
46
- styleSheetIDMap.set(s, sheetID);
47
- }
48
- if (!pastOwning.includes(sheetID)) {
49
- app.send((0, messages_gen_js_1.AdoptedSSAddOwner)(sheetID, nodeID));
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
- for (const sheetID of pastOwning) {
60
- if (!nowOwning.includes(sheetID)) {
61
- app.send((0, messages_gen_js_1.AdoptedSSRemoveOwner)(sheetID, nodeID));
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); // Misterious bug:
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
- Howerer, none of the documented methods (replace, insertRule) is triggered.
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) {