@openreplay/tracker 4.1.8 → 4.1.9-beta.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 (57) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +22 -18
  3. package/cjs/app/guards.d.ts +10 -11
  4. package/cjs/app/guards.js +2 -1
  5. package/cjs/app/index.d.ts +5 -3
  6. package/cjs/app/index.js +53 -36
  7. package/cjs/app/messages.gen.d.ts +3 -2
  8. package/cjs/app/messages.gen.js +19 -5
  9. package/cjs/app/observer/observer.js +4 -4
  10. package/cjs/app/observer/top_observer.js +1 -1
  11. package/cjs/app/session.d.ts +1 -1
  12. package/cjs/app/session.js +1 -1
  13. package/cjs/common/messages.gen.d.ts +16 -4
  14. package/cjs/index.d.ts +5 -1
  15. package/cjs/index.js +6 -4
  16. package/cjs/modules/cssrules.js +1 -1
  17. package/cjs/modules/focus.js +2 -2
  18. package/cjs/modules/img.js +1 -1
  19. package/cjs/modules/input.js +9 -17
  20. package/cjs/modules/mouse.js +1 -1
  21. package/cjs/modules/network.d.ts +28 -0
  22. package/cjs/modules/network.js +203 -0
  23. package/cjs/modules/timing.js +9 -6
  24. package/cjs/modules/viewport.js +3 -1
  25. package/cjs/utils.d.ts +1 -0
  26. package/cjs/utils.js +7 -4
  27. package/jest.config.js +11 -0
  28. package/lib/app/guards.d.ts +10 -11
  29. package/lib/app/guards.js +2 -1
  30. package/lib/app/index.d.ts +5 -3
  31. package/lib/app/index.js +54 -37
  32. package/lib/app/messages.gen.d.ts +3 -2
  33. package/lib/app/messages.gen.js +15 -2
  34. package/lib/app/observer/observer.js +4 -4
  35. package/lib/app/observer/top_observer.js +1 -1
  36. package/lib/app/session.d.ts +1 -1
  37. package/lib/app/session.js +1 -1
  38. package/lib/common/messages.gen.d.ts +16 -4
  39. package/lib/common/tsconfig.tsbuildinfo +1 -1
  40. package/lib/index.d.ts +5 -1
  41. package/lib/index.js +7 -5
  42. package/lib/modules/cssrules.js +1 -1
  43. package/lib/modules/focus.js +2 -2
  44. package/lib/modules/img.js +1 -1
  45. package/lib/modules/input.js +9 -17
  46. package/lib/modules/mouse.js +1 -1
  47. package/lib/modules/network.d.ts +28 -0
  48. package/lib/modules/network.js +200 -0
  49. package/lib/modules/timing.js +10 -7
  50. package/lib/modules/viewport.js +3 -1
  51. package/lib/utils.d.ts +1 -0
  52. package/lib/utils.js +5 -3
  53. package/package.json +8 -3
  54. package/cjs/app/messages.d.ts +0 -52
  55. package/cjs/app/messages.js +0 -234
  56. package/lib/app/messages.d.ts +0 -52
  57. package/lib/app/messages.js +0 -181
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ ## 4.1.10
2
+
3
+ - Added "tel" to supported input types
4
+ - Added `{ withCurrentTime: true }` to `tracker.getSessionURL` method which will return sessionURL with current session's timestamp
5
+ - Added Network module that captures fetch/xhr by default (with no plugin required)
6
+ - Use `timeOrigin()` instead of `performance.timing.navigationStart` in ResourceTiming messages
7
+
8
+ ## 4.1.8
9
+
10
+ - recalculate timeOrigin on start to prevent wrong timestamps on "sleeping" sessions
11
+
12
+ ## 4.1.7
13
+
14
+ - resend metadata on start
15
+
16
+ ## 4.1.6
17
+
18
+ - remove log that potentially caused crashed during slow initial render
package/README.md CHANGED
@@ -2,10 +2,14 @@
2
2
 
3
3
  The main package of the [OpenReplay](https://openreplay.com/) tracker.
4
4
 
5
+ ## Documentation
6
+
7
+ For launch options and available public methods, [refer to the documentation](https://docs.openreplay.com/installation/javascript-sdk#options)
8
+
5
9
  ## Installation
6
10
 
7
11
  ```bash
8
- npm i @openreplay/tracker
12
+ npm i @openreplay/tracker
9
13
  ```
10
14
 
11
15
  ## Usage
@@ -13,30 +17,30 @@ npm i @openreplay/tracker
13
17
  Initialize the package from your codebase entry point and start the tracker. You must set the `projectKey` option in the constructor. Its value can can be found in your OpenReplay dashboard under [Preferences -> Projects](https://app.openreplay.com/client/projects).
14
18
 
15
19
  ```js
16
- import Tracker from '@openreplay/tracker';
20
+ import Tracker from '@openreplay/tracker'
17
21
 
18
22
  const tracker = new Tracker({
19
23
  projectKey: YOUR_PROJECT_KEY,
20
- });
21
- tracker.start({
22
- userID: "Mr.Smith",
23
- metadata: {
24
- version: "3.5.0",
25
- balance: "10M",
26
- role: "admin",
27
- }
28
- }).then(startedSession => {
29
- if (startedSession.success) {
30
- console.log(startedSession)
31
- }
32
24
  })
25
+ tracker
26
+ .start({
27
+ userID: 'Mr.Smith',
28
+ metadata: {
29
+ version: '3.5.0',
30
+ balance: '10M',
31
+ role: 'admin',
32
+ },
33
+ })
34
+ .then((startedSession) => {
35
+ if (startedSession.success) {
36
+ console.log(startedSession)
37
+ }
38
+ })
33
39
  ```
34
40
 
35
41
  Then you can use OpenReplay JavaScript API anywhere in your code.
36
42
 
37
43
  ```js
38
- tracker.setUserID('my_user_id');
39
- tracker.setMetadata('env', 'prod');
44
+ tracker.setUserID('my_user_id')
45
+ tracker.setMetadata('env', 'prod')
40
46
  ```
41
-
42
- Read [our docs](https://docs.openreplay.com/) for more information.
@@ -5,17 +5,16 @@ export declare function isTextNode(node: Node): node is Text;
5
5
  export declare function isDocument(node: Node): node is Document;
6
6
  export declare function isRootNode(node: Node): node is Document | DocumentFragment;
7
7
  declare type TagTypeMap = {
8
- HTML: HTMLHtmlElement;
9
- BODY: HTMLBodyElement;
10
- IMG: HTMLImageElement;
11
- INPUT: HTMLInputElement;
12
- TEXTAREA: HTMLTextAreaElement;
13
- SELECT: HTMLSelectElement;
14
- LABEL: HTMLLabelElement;
15
- IFRAME: HTMLIFrameElement;
16
- STYLE: HTMLStyleElement;
17
- style: SVGStyleElement;
18
- LINK: HTMLLinkElement;
8
+ html: HTMLHtmlElement;
9
+ body: HTMLBodyElement;
10
+ img: HTMLImageElement;
11
+ input: HTMLInputElement;
12
+ textarea: HTMLTextAreaElement;
13
+ select: HTMLSelectElement;
14
+ label: HTMLLabelElement;
15
+ iframe: HTMLIFrameElement;
16
+ style: HTMLStyleElement | SVGStyleElement;
17
+ link: HTMLLinkElement;
19
18
  };
20
19
  export declare function hasTag<T extends keyof TagTypeMap>(el: Node, tagName: T): el is TagTypeMap[typeof tagName];
21
20
  export {};
package/cjs/app/guards.js CHANGED
@@ -27,6 +27,7 @@ function isRootNode(node) {
27
27
  }
28
28
  exports.isRootNode = isRootNode;
29
29
  function hasTag(el, tagName) {
30
- return el.nodeName === tagName;
30
+ // @ts-ignore
31
+ return el.localName === tagName;
31
32
  }
32
33
  exports.hasTag = hasTag;
@@ -75,6 +75,7 @@ export default class App {
75
75
  private readonly worker?;
76
76
  constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>);
77
77
  private _debug;
78
+ private _usingOldFetchPlugin;
78
79
  send(message: Message, urgent?: boolean): void;
79
80
  private commit;
80
81
  private delay;
@@ -100,7 +101,9 @@ export default class App {
100
101
  };
101
102
  getSessionToken(): string | undefined;
102
103
  getSessionID(): string | undefined;
103
- getSessionURL(): string | undefined;
104
+ getSessionURL(options?: {
105
+ withCurrentTime?: boolean;
106
+ }): string | undefined;
104
107
  getHost(): string;
105
108
  getProjectKey(): string;
106
109
  getBaseHref(): string;
@@ -109,8 +112,7 @@ export default class App {
109
112
  active(): boolean;
110
113
  resetNextPageSession(flag: boolean): void;
111
114
  private _start;
112
- start(options?: StartOptions): Promise<StartPromiseReturn>;
115
+ start(...args: Parameters<App['_start']>): Promise<StartPromiseReturn>;
113
116
  stop(stopWorker?: boolean): void;
114
- restart(): void;
115
117
  }
116
118
  export {};
package/cjs/app/index.js CHANGED
@@ -33,7 +33,8 @@ class App {
33
33
  this.stopCallbacks = [];
34
34
  this.commitCallbacks = [];
35
35
  this.activityState = ActivityState.NotActive;
36
- this.version = '4.1.7'; // TODO: version compatability check inside each plugin.
36
+ this.version = '4.1.9-beta.2'; // TODO: version compatability check inside each plugin.
37
+ this._usingOldFetchPlugin = false;
37
38
  this.delay = 0;
38
39
  this.projectKey = projectKey;
39
40
  this.options = Object.assign({
@@ -76,14 +77,14 @@ class App {
76
77
  this.session.applySessionHash(sessionToken);
77
78
  }
78
79
  try {
79
- 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(`Failed to send batch after ${this.attemptsCount} attempts.`):(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 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 79:return this.string(t[1])&&this.string(t[2]);case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])}}}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!==g&&(clearInterval(g),g=null),h&&(h.clean(),h=null),r&&(r.clean(),r=null),n.NotActive}function o(){postMessage("restart"),a()}n.NotActive;let c,g=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]?c=setTimeout(()=>o(),18e5):clearTimeout(c)),t.writeMessage(i)})}else{if("start"===i.type)return n.Starting,r=new t(i.ingestPoint,()=>{o()},t=>{!function(t){postMessage({type:"failure",reason:t}),a()}(t)},i.connAttemptCount,i.connAttemptGap),h=new e(i.pageNo,i.timestamp,i.url,t=>r&&r.push(t)),null===g&&(g=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' })));
80
+ 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,this.busy||this.sendNext()}push(t){this.busy||!this.token?this.queue.push(t):this.sendBatch(t)}sendNext(){const t=this.queue.shift();t?this.sendBatch(t):this.busy=!1}retry(t){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(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();i.status>=400?this.retry(t):(this.attemptsCount=0,this.sendNext())}).catch(i=>{console.warn("OpenReplay:",i),this.retry(t)})}clean(){this.queue.length=0,this.token=null}}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 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 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 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 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 79:return this.string(t[1])&&this.string(t[2]);case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])}}}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){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)||console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),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!==g&&(clearInterval(g),g=null),h&&(h.clean(),h=null),r&&(r.clean(),r=null),n.NotActive}function c(){postMessage("restart"),a()}n.NotActive;let o,g=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(()=>c(),18e5):clearTimeout(o)),t.writeMessage(i)})}else{if("start"===i.type)return n.Starting,r=new t(i.ingestPoint,()=>{c()},t=>{!function(t){postMessage({type:"failure",reason:t}),a()}(t)},i.connAttemptCount,i.connAttemptGap),h=new e(i.pageNo,i.timestamp,i.url,t=>r&&r.push(t)),null===g&&(g=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' })));
80
81
  this.worker.onerror = (e) => {
81
82
  this._debug('webworker_error', e);
82
83
  };
83
84
  this.worker.onmessage = ({ data }) => {
84
85
  if (data === 'restart') {
85
86
  this.stop(false);
86
- this.start({ forceNew: true }); // TODO: keep userID & metadata (draw scenarios)
87
+ this.start({}, true);
87
88
  }
88
89
  else if (data.type === 'failure') {
89
90
  this.stop(false);
@@ -120,9 +121,18 @@ class App {
120
121
  }
121
122
  send(message, urgent = false) {
122
123
  if (this.activityState === ActivityState.NotActive) {
123
- // this.debug.log('SendiTrying to send when not active', message) <- crashing the app
124
124
  return;
125
125
  }
126
+ // === Back compatibility with Fetch/Axios plugins ===
127
+ if (message[0] === 39 /* Fetch */) {
128
+ this._usingOldFetchPlugin = true;
129
+ (0, utils_js_1.deprecationWarn)('Fetch plugin', "'network' init option");
130
+ (0, utils_js_1.deprecationWarn)('Axios plugin', "'network' init option");
131
+ }
132
+ if (this._usingOldFetchPlugin && message[0] === 21 /* NetworkRequest */) {
133
+ return;
134
+ }
135
+ // ====================================================
126
136
  this.messages.push(message);
127
137
  // TODO: commit on start if there were `urgent` sends;
128
138
  // Clarify where urgent can be used for;
@@ -217,8 +227,8 @@ class App {
217
227
  getSessionID() {
218
228
  return this.session.getInfo().sessionID || undefined;
219
229
  }
220
- getSessionURL() {
221
- const { projectID, sessionID } = this.session.getInfo();
230
+ getSessionURL(options) {
231
+ const { projectID, sessionID, timestamp } = this.session.getInfo();
222
232
  if (!projectID || !sessionID) {
223
233
  this.debug.error('OpenReplay error: Unable to build session URL');
224
234
  return undefined;
@@ -226,7 +236,12 @@ class App {
226
236
  const ingest = this.options.ingestPoint;
227
237
  const isSaas = ingest === exports.DEFAULT_INGEST_POINT;
228
238
  const projectPath = isSaas ? ingest.replace('api', 'app') : ingest;
229
- return projectPath.replace(/ingest$/, `${projectID}/session/${sessionID}`);
239
+ const url = projectPath.replace(/ingest$/, `${projectID}/session/${sessionID}`);
240
+ if (options === null || options === void 0 ? void 0 : options.withCurrentTime) {
241
+ const jumpTo = (0, utils_js_1.now)() - timestamp;
242
+ return `${url}?jumpto=${jumpTo}`;
243
+ }
244
+ return url;
230
245
  }
231
246
  getHost() {
232
247
  return new URL(this.options.ingestPoint).host;
@@ -269,8 +284,7 @@ class App {
269
284
  this.sessionStorage.removeItem(this.options.session_reset_key);
270
285
  }
271
286
  }
272
- _start(startOpts) {
273
- (0, utils_js_1.adjustTimeOrigin)();
287
+ _start(startOpts = {}, resetByWorker = false) {
274
288
  if (!this.worker) {
275
289
  return Promise.resolve(UnsuccessfulStart('No worker found: perhaps, CSP is not set.'));
276
290
  }
@@ -278,9 +292,19 @@ class App {
278
292
  return Promise.resolve(UnsuccessfulStart('OpenReplay: trying to call `start()` on the instance that has been started already.'));
279
293
  }
280
294
  this.activityState = ActivityState.Starting;
295
+ (0, utils_js_1.adjustTimeOrigin)();
281
296
  if (startOpts.sessionHash) {
282
297
  this.session.applySessionHash(startOpts.sessionHash);
283
298
  }
299
+ if (startOpts.forceNew) {
300
+ // Reset session metadata only if requested directly
301
+ this.session.reset();
302
+ }
303
+ this.session.assign({
304
+ // MBTODO: maybe it would make sense to `forceNew` if the `userID` was changed
305
+ userID: startOpts.userID,
306
+ metadata: startOpts.metadata,
307
+ });
284
308
  const timestamp = (0, utils_js_1.now)();
285
309
  this.worker.postMessage({
286
310
  type: 'start',
@@ -291,23 +315,16 @@ class App {
291
315
  connAttemptCount: this.options.connAttemptCount,
292
316
  connAttemptGap: this.options.connAttemptGap,
293
317
  });
294
- this.session.update({
295
- // TODO: transparent "session" module logic AND explicit internal api for plugins.
296
- // "updating" with old metadata in order to trigger session's UpdateCallbacks.
297
- // (for the case of internal .start() calls, like on "restart" webworker signal or assistent connection in tracker-assist )
298
- metadata: startOpts.metadata || this.session.getInfo().metadata,
299
- userID: startOpts.userID,
300
- });
301
- const sReset = this.sessionStorage.getItem(this.options.session_reset_key);
318
+ const lsReset = this.sessionStorage.getItem(this.options.session_reset_key) !== null;
302
319
  this.sessionStorage.removeItem(this.options.session_reset_key);
303
- const shouldReset = startOpts.forceNew || sReset !== null;
320
+ const needNewSessionID = startOpts.forceNew || lsReset || resetByWorker;
304
321
  return window
305
322
  .fetch(this.options.ingestPoint + '/v1/web/start', {
306
323
  method: 'POST',
307
324
  headers: {
308
325
  'Content-Type': 'application/json',
309
326
  },
310
- body: JSON.stringify(Object.assign(Object.assign({}, this.getTrackerInfo()), { timestamp, userID: this.session.getInfo().userID, token: shouldReset ? undefined : this.session.getSessionToken(), deviceMemory: performance_js_1.deviceMemory,
327
+ body: JSON.stringify(Object.assign(Object.assign({}, this.getTrackerInfo()), { timestamp, userID: this.session.getInfo().userID, token: needNewSessionID ? undefined : this.session.getSessionToken(), deviceMemory: performance_js_1.deviceMemory,
311
328
  jsHeapSizeLimit: performance_js_1.jsHeapSizeLimit })),
312
329
  })
313
330
  .then((r) => {
@@ -327,25 +344,29 @@ class App {
327
344
  return Promise.reject('no worker found after start request (this might not happen)');
328
345
  }
329
346
  if (this.activityState === ActivityState.NotActive) {
330
- return Promise.reject('Tracker stopped during authorisation');
347
+ return Promise.reject('Tracker stopped during authorization');
331
348
  }
332
- const { token, userUUID, sessionID, projectID, beaconSizeLimit, startTimestamp, // real startTS, derived from sessionID
333
- delay, } = r;
349
+ const { token, userUUID, projectID, beaconSizeLimit, delay, // derived from token
350
+ sessionID, // derived from token
351
+ startTimestamp, // real startTS (server time), derived from sessionID
352
+ } = r;
334
353
  if (typeof token !== 'string' ||
335
354
  typeof userUUID !== 'string' ||
336
- //typeof startTimestamp !== 'number' ||
337
- //typeof sessionID !== 'string' ||
355
+ (typeof startTimestamp !== 'number' && typeof startTimestamp !== 'undefined') ||
356
+ typeof sessionID !== 'string' ||
338
357
  typeof delay !== 'number' ||
339
358
  (typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) {
340
359
  return Promise.reject(`Incorrect server response: ${JSON.stringify(r)}`);
341
360
  }
342
361
  this.delay = delay;
343
- const prevSessionID = this.session.getInfo().sessionID;
344
- if (prevSessionID && prevSessionID !== sessionID) {
345
- this.session.reset();
346
- }
347
362
  this.session.setSessionToken(token);
348
- this.session.update({ sessionID, timestamp: startTimestamp || timestamp, projectID }); // TODO: no no-explicit 'any'
363
+ this.session.assign({
364
+ sessionID,
365
+ timestamp: startTimestamp || timestamp,
366
+ projectID,
367
+ });
368
+ // (Re)send Metadata for the case of a new session
369
+ Object.entries(this.session.getInfo().metadata).forEach(([key, value]) => this.send((0, messages_gen_js_1.Metadata)(key, value)));
349
370
  this.localStorage.setItem(this.options.local_uuid_key, userUUID);
350
371
  this.worker.postMessage({
351
372
  type: 'auth',
@@ -376,16 +397,16 @@ class App {
376
397
  return UnsuccessfulStart(START_ERROR);
377
398
  });
378
399
  }
379
- start(options = {}) {
400
+ start(...args) {
380
401
  if (!document.hidden) {
381
- return this._start(options);
402
+ return this._start(...args);
382
403
  }
383
404
  else {
384
405
  return new Promise((resolve) => {
385
406
  const onVisibilityChange = () => {
386
407
  if (!document.hidden) {
387
408
  document.removeEventListener('visibilitychange', onVisibilityChange);
388
- resolve(this._start(options));
409
+ resolve(this._start(...args));
389
410
  }
390
411
  };
391
412
  document.addEventListener('visibilitychange', onVisibilityChange);
@@ -410,9 +431,5 @@ class App {
410
431
  }
411
432
  }
412
433
  }
413
- restart() {
414
- this.stop(false);
415
- this.start({ forceNew: false });
416
- }
417
434
  }
418
435
  exports.default = App;
@@ -1,5 +1,5 @@
1
1
  import * as Messages from '../common/messages.gen.js';
2
- export { default } from '../common/messages.gen.js';
2
+ export { default, Type } from '../common/messages.gen.js';
3
3
  export declare function BatchMetadata(version: number, pageNo: number, firstIndex: number, timestamp: number, location: string): Messages.BatchMetadata;
4
4
  export declare function PartitionedMessage(partNo: number, partTotal: number): Messages.PartitionedMessage;
5
5
  export declare function Timestamp(timestamp: number): Messages.Timestamp;
@@ -19,11 +19,12 @@ export declare function SetInputTarget(id: number, label: string): Messages.SetI
19
19
  export declare function SetInputValue(id: number, value: string, mask: number): Messages.SetInputValue;
20
20
  export declare function SetInputChecked(id: number, checked: boolean): Messages.SetInputChecked;
21
21
  export declare function MouseMove(x: number, y: number): Messages.MouseMove;
22
+ export declare function NetworkRequest(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number): Messages.NetworkRequest;
22
23
  export declare function ConsoleLog(level: string, value: string): Messages.ConsoleLog;
23
24
  export declare function PageLoadTiming(requestStart: number, responseStart: number, responseEnd: number, domContentLoadedEventStart: number, domContentLoadedEventEnd: number, loadEventStart: number, loadEventEnd: number, firstPaint: number, firstContentfulPaint: number): Messages.PageLoadTiming;
24
25
  export declare function PageRenderTiming(speedIndex: number, visuallyComplete: number, timeToInteractive: number): Messages.PageRenderTiming;
25
26
  export declare function JSExceptionDeprecated(name: string, message: string, payload: string): Messages.JSExceptionDeprecated;
26
- export declare function RawCustomEvent(name: string, payload: string): Messages.RawCustomEvent;
27
+ export declare function CustomEvent(name: string, payload: string): Messages.CustomEvent;
27
28
  export declare function UserID(id: string): Messages.UserID;
28
29
  export declare function UserAnonymousID(id: string): Messages.UserAnonymousID;
29
30
  export declare function Metadata(key: string, value: string): Messages.Metadata;
@@ -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.ResourceTiming = 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.RawCustomEvent = exports.JSExceptionDeprecated = exports.PageRenderTiming = exports.PageLoadTiming = exports.ConsoleLog = 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 = exports.PartitionedMessage = exports.BatchMetadata = void 0;
6
- exports.JSException = exports.Zustand = exports.AdoptedSSRemoveOwner = exports.AdoptedSSAddOwner = exports.AdoptedSSDeleteRule = exports.AdoptedSSInsertRuleURLBased = exports.AdoptedSSReplaceURLBased = exports.CreateIFrameDocument = exports.MouseClick = void 0;
5
+ exports.CustomIssue = exports.TechnicalInfo = exports.SetCSSDataURLBased = exports.SetNodeAttributeURLBased = exports.LongTask = exports.SetNodeFocus = exports.LoadFontFace = exports.SetPageVisibility = exports.ConnectionInformation = exports.ResourceTiming = 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.JSExceptionDeprecated = 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 = exports.PartitionedMessage = exports.BatchMetadata = void 0;
6
+ exports.JSException = exports.Zustand = exports.AdoptedSSRemoveOwner = exports.AdoptedSSAddOwner = exports.AdoptedSSDeleteRule = exports.AdoptedSSInsertRuleURLBased = exports.AdoptedSSReplaceURLBased = exports.CreateIFrameDocument = exports.MouseClick = exports.CSSInsertRuleURLBased = void 0;
7
7
  function BatchMetadata(version, pageNo, firstIndex, timestamp, location) {
8
8
  return [
9
9
  81 /* BatchMetadata */,
@@ -164,6 +164,20 @@ function MouseMove(x, y) {
164
164
  ];
165
165
  }
166
166
  exports.MouseMove = MouseMove;
167
+ function NetworkRequest(type, method, url, request, response, status, timestamp, duration) {
168
+ return [
169
+ 21 /* NetworkRequest */,
170
+ type,
171
+ method,
172
+ url,
173
+ request,
174
+ response,
175
+ status,
176
+ timestamp,
177
+ duration,
178
+ ];
179
+ }
180
+ exports.NetworkRequest = NetworkRequest;
167
181
  function ConsoleLog(level, value) {
168
182
  return [
169
183
  22 /* ConsoleLog */,
@@ -205,14 +219,14 @@ function JSExceptionDeprecated(name, message, payload) {
205
219
  ];
206
220
  }
207
221
  exports.JSExceptionDeprecated = JSExceptionDeprecated;
208
- function RawCustomEvent(name, payload) {
222
+ function CustomEvent(name, payload) {
209
223
  return [
210
- 27 /* RawCustomEvent */,
224
+ 27 /* CustomEvent */,
211
225
  name,
212
226
  payload,
213
227
  ];
214
228
  }
215
- exports.RawCustomEvent = RawCustomEvent;
229
+ exports.CustomEvent = CustomEvent;
216
230
  function UserID(id) {
217
231
  return [
218
232
  28 /* UserID */,
@@ -125,7 +125,7 @@ class Observer {
125
125
  return;
126
126
  }
127
127
  if (name === 'value' &&
128
- (0, guards_js_1.hasTag)(node, 'INPUT') &&
128
+ (0, guards_js_1.hasTag)(node, 'input') &&
129
129
  node.type !== 'button' &&
130
130
  node.type !== 'reset' &&
131
131
  node.type !== 'submit') {
@@ -135,7 +135,7 @@ class Observer {
135
135
  this.app.send((0, messages_gen_js_1.RemoveNodeAttribute)(id, name));
136
136
  return;
137
137
  }
138
- if (name === 'style' || (name === 'href' && (0, guards_js_1.hasTag)(node, 'LINK'))) {
138
+ if (name === 'style' || (name === 'href' && (0, guards_js_1.hasTag)(node, 'link'))) {
139
139
  this.app.send((0, messages_gen_js_1.SetNodeAttributeURLBased)(id, name, value, this.app.getBaseHref()));
140
140
  return;
141
141
  }
@@ -145,7 +145,7 @@ class Observer {
145
145
  this.app.send((0, messages_gen_js_1.SetNodeAttribute)(id, name, value));
146
146
  }
147
147
  sendNodeData(id, parentElement, data) {
148
- if ((0, guards_js_1.hasTag)(parentElement, 'STYLE') || (0, guards_js_1.hasTag)(parentElement, 'style')) {
148
+ if ((0, guards_js_1.hasTag)(parentElement, 'style')) {
149
149
  this.app.send((0, messages_gen_js_1.SetCSSDataURLBased)(id, data, this.app.getBaseHref()));
150
150
  return;
151
151
  }
@@ -206,7 +206,7 @@ class Observer {
206
206
  // Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
207
207
  // TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
208
208
  // TODO: Clean the logic (though now it workd fine)
209
- if (!(0, guards_js_1.hasTag)(node, 'HTML') || !this.isTopContext) {
209
+ if (!(0, guards_js_1.hasTag)(node, 'html') || !this.isTopContext) {
210
210
  if (parent === null) {
211
211
  // Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
212
212
  // That shouldn't affect the visual rendering ( should it? maybe when transition applied? )
@@ -22,7 +22,7 @@ class TopObserver extends observer_js_1.default {
22
22
  }, options);
23
23
  // IFrames
24
24
  this.app.nodes.attachNodeCallback((node) => {
25
- if ((0, guards_js_1.hasTag)(node, 'IFRAME') &&
25
+ if ((0, guards_js_1.hasTag)(node, 'iframe') &&
26
26
  ((this.options.captureIFrames && !(0, utils_js_1.hasOpenreplayAttribute)(node, 'obscured')) ||
27
27
  (0, utils_js_1.hasOpenreplayAttribute)(node, 'capture'))) {
28
28
  this.handleIframe(node);
@@ -23,7 +23,7 @@ export default class Session {
23
23
  constructor(app: App, options: Options);
24
24
  attachUpdateCallback(cb: OnUpdateCallback): void;
25
25
  private handleUpdate;
26
- update(newInfo: Partial<SessionInfo>): void;
26
+ assign(newInfo: Partial<SessionInfo>): void;
27
27
  setMetadata(key: string, value: string): void;
28
28
  setUserID(userID: string): void;
29
29
  private getPageNumber;
@@ -21,7 +21,7 @@ class Session {
21
21
  }
22
22
  this.callbacks.forEach((cb) => cb(newInfo));
23
23
  }
24
- update(newInfo) {
24
+ assign(newInfo) {
25
25
  if (newInfo.userID !== undefined) {
26
26
  // TODO clear nullable/undefinable types
27
27
  this.userID = newInfo.userID;
@@ -18,11 +18,12 @@ export declare const enum Type {
18
18
  SetInputValue = 18,
19
19
  SetInputChecked = 19,
20
20
  MouseMove = 20,
21
+ NetworkRequest = 21,
21
22
  ConsoleLog = 22,
22
23
  PageLoadTiming = 23,
23
24
  PageRenderTiming = 24,
24
25
  JSExceptionDeprecated = 25,
25
- RawCustomEvent = 27,
26
+ CustomEvent = 27,
26
27
  UserID = 28,
27
28
  UserAnonymousID = 29,
28
29
  Metadata = 30,
@@ -162,6 +163,17 @@ export declare type MouseMove = [
162
163
  number,
163
164
  number
164
165
  ];
166
+ export declare type NetworkRequest = [
167
+ Type.NetworkRequest,
168
+ string,
169
+ string,
170
+ string,
171
+ string,
172
+ string,
173
+ number,
174
+ number,
175
+ number
176
+ ];
165
177
  export declare type ConsoleLog = [
166
178
  Type.ConsoleLog,
167
179
  string,
@@ -191,8 +203,8 @@ export declare type JSExceptionDeprecated = [
191
203
  string,
192
204
  string
193
205
  ];
194
- export declare type RawCustomEvent = [
195
- Type.RawCustomEvent,
206
+ export declare type CustomEvent = [
207
+ Type.CustomEvent,
196
208
  string,
197
209
  string
198
210
  ];
@@ -405,5 +417,5 @@ export declare type JSException = [
405
417
  string,
406
418
  string
407
419
  ];
408
- declare type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | ConsoleLog | PageLoadTiming | PageRenderTiming | JSExceptionDeprecated | RawCustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | ResourceTiming | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | Zustand | JSException;
420
+ declare type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequest | ConsoleLog | PageLoadTiming | PageRenderTiming | JSExceptionDeprecated | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | ResourceTiming | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | Zustand | JSException;
409
421
  export default Message;
package/cjs/index.d.ts CHANGED
@@ -9,6 +9,7 @@ import type { Options as ExceptionOptions } from './modules/exception.js';
9
9
  import type { Options as InputOptions } from './modules/input.js';
10
10
  import type { Options as PerformanceOptions } from './modules/performance.js';
11
11
  import type { Options as TimingOptions } from './modules/timing.js';
12
+ import type { Options as NetworkOptions } from './modules/network.js';
12
13
  import type { StartOptions } from './app/index.js';
13
14
  import type { StartPromiseReturn } from './app/index.js';
14
15
  export declare type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & InputOptions & PerformanceOptions & TimingOptions> & {
@@ -17,6 +18,7 @@ export declare type Options = Partial<AppOptions & ConsoleOptions & ExceptionOpt
17
18
  sessionToken?: string;
18
19
  respectDoNotTrack?: boolean;
19
20
  autoResetOnWindowOpen?: boolean;
21
+ network?: NetworkOptions;
20
22
  __DISABLE_SECURE_MODE?: boolean;
21
23
  };
22
24
  export default class API {
@@ -30,7 +32,9 @@ export default class API {
30
32
  getSessionToken(): string | null | undefined;
31
33
  getSessionID(): string | null | undefined;
32
34
  sessionID(): string | null | undefined;
33
- getSessionURL(): string | undefined;
35
+ getSessionURL(options?: {
36
+ withCurrentTime?: boolean;
37
+ }): string | undefined;
34
38
  setUserID(id: string): void;
35
39
  userID(id: string): void;
36
40
  setUserAnonymousID(id: string): void;