@openreplay/tracker 3.6.0 → 3.6.3

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