@openreplay/tracker 4.1.9-beta.1 → 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.
- package/CHANGELOG.md +18 -0
- package/README.md +22 -18
- package/cjs/app/guards.d.ts +10 -11
- package/cjs/app/guards.js +2 -1
- package/cjs/app/index.d.ts +4 -1
- package/cjs/app/index.js +22 -6
- package/cjs/app/messages.gen.d.ts +2 -1
- package/cjs/app/messages.gen.js +16 -2
- package/cjs/app/observer/observer.js +4 -4
- package/cjs/app/observer/top_observer.js +1 -1
- package/cjs/common/messages.gen.d.ts +13 -1
- package/cjs/index.d.ts +5 -1
- package/cjs/index.js +5 -3
- package/cjs/modules/cssrules.js +1 -1
- package/cjs/modules/focus.js +2 -2
- package/cjs/modules/img.js +1 -1
- package/cjs/modules/input.js +9 -17
- package/cjs/modules/mouse.js +1 -1
- package/cjs/modules/network.d.ts +28 -0
- package/cjs/modules/network.js +203 -0
- package/cjs/modules/timing.js +7 -3
- package/jest.config.js +11 -0
- package/lib/app/guards.d.ts +10 -11
- package/lib/app/guards.js +2 -1
- package/lib/app/index.d.ts +4 -1
- package/lib/app/index.js +23 -7
- package/lib/app/messages.gen.d.ts +2 -1
- package/lib/app/messages.gen.js +13 -0
- package/lib/app/observer/observer.js +4 -4
- package/lib/app/observer/top_observer.js +1 -1
- package/lib/common/messages.gen.d.ts +13 -1
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/index.d.ts +5 -1
- package/lib/index.js +5 -3
- package/lib/modules/cssrules.js +1 -1
- package/lib/modules/focus.js +2 -2
- package/lib/modules/img.js +1 -1
- package/lib/modules/input.js +9 -17
- package/lib/modules/mouse.js +1 -1
- package/lib/modules/network.d.ts +28 -0
- package/lib/modules/network.js +200 -0
- package/lib/modules/timing.js +8 -4
- package/package.json +8 -3
- package/cjs/app/messages.d.ts +0 -52
- package/cjs/app/messages.js +0 -234
- package/lib/app/messages.d.ts +0 -52
- 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.
|
package/cjs/app/guards.d.ts
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
package/cjs/app/index.d.ts
CHANGED
|
@@ -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(
|
|
104
|
+
getSessionURL(options?: {
|
|
105
|
+
withCurrentTime?: boolean;
|
|
106
|
+
}): string | undefined;
|
|
104
107
|
getHost(): string;
|
|
105
108
|
getProjectKey(): string;
|
|
106
109
|
getBaseHref(): string;
|
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.9-beta.
|
|
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,7 +77,7 @@ 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();
|
|
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
|
};
|
|
@@ -122,6 +123,16 @@ class App {
|
|
|
122
123
|
if (this.activityState === ActivityState.NotActive) {
|
|
123
124
|
return;
|
|
124
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
|
+
// ====================================================
|
|
125
136
|
this.messages.push(message);
|
|
126
137
|
// TODO: commit on start if there were `urgent` sends;
|
|
127
138
|
// Clarify where urgent can be used for;
|
|
@@ -216,8 +227,8 @@ class App {
|
|
|
216
227
|
getSessionID() {
|
|
217
228
|
return this.session.getInfo().sessionID || undefined;
|
|
218
229
|
}
|
|
219
|
-
getSessionURL() {
|
|
220
|
-
const { projectID, sessionID } = this.session.getInfo();
|
|
230
|
+
getSessionURL(options) {
|
|
231
|
+
const { projectID, sessionID, timestamp } = this.session.getInfo();
|
|
221
232
|
if (!projectID || !sessionID) {
|
|
222
233
|
this.debug.error('OpenReplay error: Unable to build session URL');
|
|
223
234
|
return undefined;
|
|
@@ -225,7 +236,12 @@ class App {
|
|
|
225
236
|
const ingest = this.options.ingestPoint;
|
|
226
237
|
const isSaas = ingest === exports.DEFAULT_INGEST_POINT;
|
|
227
238
|
const projectPath = isSaas ? ingest.replace('api', 'app') : ingest;
|
|
228
|
-
|
|
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;
|
|
229
245
|
}
|
|
230
246
|
getHost() {
|
|
231
247
|
return new URL(this.options.ingestPoint).host;
|
|
@@ -328,7 +344,7 @@ class App {
|
|
|
328
344
|
return Promise.reject('no worker found after start request (this might not happen)');
|
|
329
345
|
}
|
|
330
346
|
if (this.activityState === ActivityState.NotActive) {
|
|
331
|
-
return Promise.reject('Tracker stopped during
|
|
347
|
+
return Promise.reject('Tracker stopped during authorization');
|
|
332
348
|
}
|
|
333
349
|
const { token, userUUID, projectID, beaconSizeLimit, delay, // derived from token
|
|
334
350
|
sessionID, // derived from token
|
|
@@ -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,6 +19,7 @@ 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;
|
package/cjs/app/messages.gen.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Auto-generated, do not edit
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.
|
|
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 */,
|
|
@@ -125,7 +125,7 @@ class Observer {
|
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
if (name === 'value' &&
|
|
128
|
-
(0, guards_js_1.hasTag)(node, '
|
|
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, '
|
|
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, '
|
|
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, '
|
|
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, '
|
|
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);
|
|
@@ -18,6 +18,7 @@ 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,
|
|
@@ -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,
|
|
@@ -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 | 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;
|
|
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(
|
|
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;
|
package/cjs/index.js
CHANGED
|
@@ -22,6 +22,7 @@ const viewport_js_1 = require("./modules/viewport.js");
|
|
|
22
22
|
const cssrules_js_1 = require("./modules/cssrules.js");
|
|
23
23
|
const focus_js_1 = require("./modules/focus.js");
|
|
24
24
|
const fonts_js_1 = require("./modules/fonts.js");
|
|
25
|
+
const network_js_1 = require("./modules/network.js");
|
|
25
26
|
const constructedStyleSheets_js_1 = require("./modules/constructedStyleSheets.js");
|
|
26
27
|
const utils_js_1 = require("./utils.js");
|
|
27
28
|
const DOCS_SETUP = '/installation/setup-or';
|
|
@@ -114,6 +115,7 @@ class API {
|
|
|
114
115
|
(0, scroll_js_1.default)(app);
|
|
115
116
|
(0, focus_js_1.default)(app);
|
|
116
117
|
(0, fonts_js_1.default)(app);
|
|
118
|
+
(0, network_js_1.default)(app, options.network);
|
|
117
119
|
window.__OPENREPLAY__ = this;
|
|
118
120
|
if (options.autoResetOnWindowOpen) {
|
|
119
121
|
const wOpen = window.open;
|
|
@@ -138,7 +140,7 @@ class API {
|
|
|
138
140
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
139
141
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
140
142
|
req.send(JSON.stringify({
|
|
141
|
-
trackerVersion: '4.1.9-beta.
|
|
143
|
+
trackerVersion: '4.1.9-beta.2',
|
|
142
144
|
projectKey: options.projectKey,
|
|
143
145
|
doNotTrack,
|
|
144
146
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -188,11 +190,11 @@ class API {
|
|
|
188
190
|
(0, utils_js_1.deprecationWarn)("'sessionID' method", "'getSessionID' method", '/');
|
|
189
191
|
return this.getSessionID();
|
|
190
192
|
}
|
|
191
|
-
getSessionURL() {
|
|
193
|
+
getSessionURL(options) {
|
|
192
194
|
if (this.app === null) {
|
|
193
195
|
return undefined;
|
|
194
196
|
}
|
|
195
|
-
return this.app.getSessionURL();
|
|
197
|
+
return this.app.getSessionURL(options);
|
|
196
198
|
}
|
|
197
199
|
setUserID(id) {
|
|
198
200
|
if (typeof id === 'string' && this.app !== null) {
|
package/cjs/modules/cssrules.js
CHANGED
|
@@ -76,7 +76,7 @@ function default_1(app) {
|
|
|
76
76
|
patchContext(window);
|
|
77
77
|
app.observer.attachContextCallback(patchContext);
|
|
78
78
|
app.nodes.attachNodeCallback((node) => {
|
|
79
|
-
if (!((0, guards_js_1.hasTag)(node, '
|
|
79
|
+
if (!((0, guards_js_1.hasTag)(node, 'style')) || !node.sheet) {
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
82
|
if (node.textContent !== null && node.textContent.trim().length > 0) {
|
package/cjs/modules/focus.js
CHANGED
|
@@ -11,7 +11,7 @@ function default_1(app) {
|
|
|
11
11
|
}
|
|
12
12
|
let blurred = false;
|
|
13
13
|
app.nodes.attachNodeCallback((node) => {
|
|
14
|
-
if (!(0, guards_js_1.hasTag)(node, '
|
|
14
|
+
if (!(0, guards_js_1.hasTag)(node, 'body')) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
app.nodes.attachNodeListener(node, 'focus', (e) => {
|
|
@@ -34,7 +34,7 @@ function default_1(app) {
|
|
|
34
34
|
});
|
|
35
35
|
app.attachStartCallback(() => {
|
|
36
36
|
let elem = document.activeElement;
|
|
37
|
-
while (elem && (0, guards_js_1.hasTag)(elem, '
|
|
37
|
+
while (elem && (0, guards_js_1.hasTag)(elem, 'iframe') && elem.contentDocument) {
|
|
38
38
|
elem = elem.contentDocument.activeElement;
|
|
39
39
|
}
|
|
40
40
|
if (elem && elem !== elem.ownerDocument.body) {
|
package/cjs/modules/img.js
CHANGED
|
@@ -97,7 +97,7 @@ function default_1(app) {
|
|
|
97
97
|
observer.disconnect();
|
|
98
98
|
});
|
|
99
99
|
app.nodes.attachNodeCallback((node) => {
|
|
100
|
-
if (!(0, guards_js_1.hasTag)(node, '
|
|
100
|
+
if (!(0, guards_js_1.hasTag)(node, 'img')) {
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
103
|
app.nodes.attachNodeListener(node, 'error', () => sendImgError(node));
|
package/cjs/modules/input.js
CHANGED
|
@@ -4,18 +4,18 @@ exports.getInputLabel = void 0;
|
|
|
4
4
|
const utils_js_1 = require("../utils.js");
|
|
5
5
|
const guards_js_1 = require("../app/guards.js");
|
|
6
6
|
const messages_gen_js_1 = require("../app/messages.gen.js");
|
|
7
|
-
const INPUT_TYPES = ['text', 'password', 'email', 'search', 'number', 'range', 'date'];
|
|
7
|
+
const INPUT_TYPES = ['text', 'password', 'email', 'search', 'number', 'range', 'date', 'tel'];
|
|
8
8
|
function isTextEditable(node) {
|
|
9
|
-
if ((0, guards_js_1.hasTag)(node, '
|
|
9
|
+
if ((0, guards_js_1.hasTag)(node, 'textarea')) {
|
|
10
10
|
return true;
|
|
11
11
|
}
|
|
12
|
-
if (!(0, guards_js_1.hasTag)(node, '
|
|
12
|
+
if (!(0, guards_js_1.hasTag)(node, 'input')) {
|
|
13
13
|
return false;
|
|
14
14
|
}
|
|
15
15
|
return INPUT_TYPES.includes(node.type);
|
|
16
16
|
}
|
|
17
17
|
function isCheckable(node) {
|
|
18
|
-
if (!(0, guards_js_1.hasTag)(node, '
|
|
18
|
+
if (!(0, guards_js_1.hasTag)(node, 'input')) {
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
const type = node.type;
|
|
@@ -25,7 +25,7 @@ const labelElementFor = utils_js_1.IN_BROWSER && 'labels' in HTMLInputElement.pr
|
|
|
25
25
|
? (node) => {
|
|
26
26
|
let p = node;
|
|
27
27
|
while ((p = p.parentNode) !== null) {
|
|
28
|
-
if ((0, guards_js_1.hasTag)(p, '
|
|
28
|
+
if ((0, guards_js_1.hasTag)(p, 'label')) {
|
|
29
29
|
return p;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -37,7 +37,7 @@ const labelElementFor = utils_js_1.IN_BROWSER && 'labels' in HTMLInputElement.pr
|
|
|
37
37
|
: (node) => {
|
|
38
38
|
let p = node;
|
|
39
39
|
while ((p = p.parentNode) !== null) {
|
|
40
|
-
if ((0, guards_js_1.hasTag)(p, '
|
|
40
|
+
if ((0, guards_js_1.hasTag)(p, 'label')) {
|
|
41
41
|
return p;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -115,11 +115,7 @@ function default_1(app, opts) {
|
|
|
115
115
|
inputValues.forEach((value, id) => {
|
|
116
116
|
const node = app.nodes.getNode(id);
|
|
117
117
|
if (!node)
|
|
118
|
-
return;
|
|
119
|
-
if (!isTextEditable(node)) {
|
|
120
|
-
inputValues.delete(id);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
118
|
+
return inputValues.delete(id);
|
|
123
119
|
if (value !== node.value) {
|
|
124
120
|
inputValues.set(id, node.value);
|
|
125
121
|
if (!registeredTargets.has(id)) {
|
|
@@ -132,11 +128,7 @@ function default_1(app, opts) {
|
|
|
132
128
|
checkableValues.forEach((checked, id) => {
|
|
133
129
|
const node = app.nodes.getNode(id);
|
|
134
130
|
if (!node)
|
|
135
|
-
return;
|
|
136
|
-
if (!isCheckable(node)) {
|
|
137
|
-
checkableValues.delete(id);
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
131
|
+
return checkableValues.delete(id);
|
|
140
132
|
if (checked !== node.checked) {
|
|
141
133
|
checkableValues.set(id, node.checked);
|
|
142
134
|
app.send((0, messages_gen_js_1.SetInputChecked)(id, node.checked));
|
|
@@ -150,7 +142,7 @@ function default_1(app, opts) {
|
|
|
150
142
|
return;
|
|
151
143
|
}
|
|
152
144
|
// TODO: support multiple select (?): use selectedOptions; Need send target?
|
|
153
|
-
if ((0, guards_js_1.hasTag)(node, '
|
|
145
|
+
if ((0, guards_js_1.hasTag)(node, 'select')) {
|
|
154
146
|
sendInputValue(id, node);
|
|
155
147
|
app.attachEventListener(node, 'change', () => {
|
|
156
148
|
sendInputValue(id, node);
|
package/cjs/modules/mouse.js
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type App from '../app/index.js';
|
|
2
|
+
declare type XHRRequestBody = Parameters<XMLHttpRequest['send']>[0];
|
|
3
|
+
declare type FetchRequestBody = RequestInit['body'];
|
|
4
|
+
interface RequestData {
|
|
5
|
+
body: XHRRequestBody | FetchRequestBody;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
interface ResponseData {
|
|
9
|
+
body: any;
|
|
10
|
+
headers: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
interface RequestResponseData {
|
|
13
|
+
readonly status: number;
|
|
14
|
+
readonly method: string;
|
|
15
|
+
url: string;
|
|
16
|
+
request: RequestData;
|
|
17
|
+
response: ResponseData;
|
|
18
|
+
}
|
|
19
|
+
declare type Sanitizer = (data: RequestResponseData) => RequestResponseData | null;
|
|
20
|
+
export interface Options {
|
|
21
|
+
sessionTokenHeader: string | boolean;
|
|
22
|
+
failuresOnly: boolean;
|
|
23
|
+
ignoreHeaders: Array<string> | boolean;
|
|
24
|
+
capturePayload: boolean;
|
|
25
|
+
sanitizer?: Sanitizer;
|
|
26
|
+
}
|
|
27
|
+
export default function (app: App, opts?: Partial<Options>): void;
|
|
28
|
+
export {};
|