@midscene/recorder-ui 1.17.3 → 1.17.4

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.
@@ -180,6 +180,7 @@
180
180
  scrollThrottleDelay = RECORDER_SCROLL_BATCH_DELAY_MS;
181
181
  inputThrottleTimer = null;
182
182
  inputThrottleDelay = RECORDER_INPUT_BATCH_DELAY_MS;
183
+ pendingInputEvent = null;
183
184
  lastViewportScroll = null;
184
185
  sessionId;
185
186
  mutationObserver = null;
@@ -218,16 +219,13 @@
218
219
  }
219
220
  stop() {
220
221
  if (!this.isRecording) return void debugLog('Recording not active, ignoring stop request');
221
- this.isRecording = false;
222
222
  debugLog('Stopping event recording');
223
223
  if (this.scrollThrottleTimer) {
224
224
  clearTimeout(this.scrollThrottleTimer);
225
225
  this.scrollThrottleTimer = null;
226
226
  }
227
- if (this.inputThrottleTimer) {
228
- clearTimeout(this.inputThrottleTimer);
229
- this.inputThrottleTimer = null;
230
- }
227
+ this.flushPendingInput();
228
+ this.isRecording = false;
231
229
  document.removeEventListener('click', this.handleClick, true);
232
230
  document.removeEventListener('input', this.handleInput);
233
231
  document.removeEventListener('scroll', this.handleScroll, true);
@@ -235,6 +233,7 @@
235
233
  }
236
234
  handleClick = (event)=>{
237
235
  if (!this.isRecording) return;
236
+ this.flushPendingInput();
238
237
  const target = event.target;
239
238
  const { isLabelClick, labelInfo } = this.checkLabelClick(target);
240
239
  const rect = target.getBoundingClientRect();
@@ -322,35 +321,34 @@
322
321
  width: Number(rect.width.toFixed(2)),
323
322
  height: Number(rect.height.toFixed(2))
324
323
  };
325
- if (this.inputThrottleTimer) clearTimeout(this.inputThrottleTimer);
326
- this.inputThrottleTimer = window.setTimeout(()=>{
327
- if (this.isRecording) {
328
- const inputEvent = {
329
- type: 'input',
330
- value: 'password' !== target.type ? target.value : '*****',
331
- timestamp: Date.now(),
332
- hashId: recorder_generateHashId('input', {
333
- ...elementRect
334
- }),
335
- element: target,
336
- inputType: target.type || 'text',
337
- elementRect,
338
- pageInfo: {
339
- width: window.innerWidth,
340
- height: window.innerHeight
341
- }
342
- };
343
- debugLog('Throttled input event:', {
344
- value: inputEvent.value,
345
- timestamp: inputEvent.timestamp,
346
- target: target.tagName,
347
- inputType: target.type
348
- });
349
- this.eventCallback(inputEvent);
324
+ if (this.pendingInputEvent?.element !== target) this.flushPendingInput();
325
+ if (null !== this.inputThrottleTimer) clearTimeout(this.inputThrottleTimer);
326
+ this.pendingInputEvent = {
327
+ type: 'input',
328
+ value: 'password' !== target.type ? target.value : '*****',
329
+ timestamp: Date.now(),
330
+ hashId: recorder_generateHashId('input', elementRect),
331
+ element: target,
332
+ inputType: target.type || 'text',
333
+ elementRect,
334
+ pageInfo: {
335
+ width: window.innerWidth,
336
+ height: window.innerHeight
350
337
  }
351
- this.inputThrottleTimer = null;
352
- }, this.inputThrottleDelay);
338
+ };
339
+ this.inputThrottleTimer = window.setTimeout(()=>this.flushPendingInput(), this.inputThrottleDelay);
353
340
  };
341
+ flushPendingInput() {
342
+ if (null !== this.inputThrottleTimer) {
343
+ clearTimeout(this.inputThrottleTimer);
344
+ this.inputThrottleTimer = null;
345
+ }
346
+ if (this.pendingInputEvent) {
347
+ const inputEvent = this.pendingInputEvent;
348
+ this.pendingInputEvent = null;
349
+ this.eventCallback(inputEvent);
350
+ }
351
+ }
354
352
  checkLabelClick(target) {
355
353
  let isLabelClick = false;
356
354
  let labelInfo;
package/dist/recorder.js CHANGED
@@ -30,6 +30,7 @@ class EventRecorder {
30
30
  scrollThrottleDelay = RECORDER_SCROLL_BATCH_DELAY_MS;
31
31
  inputThrottleTimer = null;
32
32
  inputThrottleDelay = RECORDER_INPUT_BATCH_DELAY_MS;
33
+ pendingInputEvent = null;
33
34
  lastViewportScroll = null;
34
35
  sessionId;
35
36
  mutationObserver = null;
@@ -68,16 +69,13 @@ class EventRecorder {
68
69
  }
69
70
  stop() {
70
71
  if (!this.isRecording) return void debugLog('Recording not active, ignoring stop request');
71
- this.isRecording = false;
72
72
  debugLog('Stopping event recording');
73
73
  if (this.scrollThrottleTimer) {
74
74
  clearTimeout(this.scrollThrottleTimer);
75
75
  this.scrollThrottleTimer = null;
76
76
  }
77
- if (this.inputThrottleTimer) {
78
- clearTimeout(this.inputThrottleTimer);
79
- this.inputThrottleTimer = null;
80
- }
77
+ this.flushPendingInput();
78
+ this.isRecording = false;
81
79
  document.removeEventListener('click', this.handleClick, true);
82
80
  document.removeEventListener('input', this.handleInput);
83
81
  document.removeEventListener('scroll', this.handleScroll, true);
@@ -85,6 +83,7 @@ class EventRecorder {
85
83
  }
86
84
  handleClick = (event)=>{
87
85
  if (!this.isRecording) return;
86
+ this.flushPendingInput();
88
87
  const target = event.target;
89
88
  const { isLabelClick, labelInfo } = this.checkLabelClick(target);
90
89
  const rect = target.getBoundingClientRect();
@@ -172,35 +171,34 @@ class EventRecorder {
172
171
  width: Number(rect.width.toFixed(2)),
173
172
  height: Number(rect.height.toFixed(2))
174
173
  };
175
- if (this.inputThrottleTimer) clearTimeout(this.inputThrottleTimer);
176
- this.inputThrottleTimer = window.setTimeout(()=>{
177
- if (this.isRecording) {
178
- const inputEvent = {
179
- type: 'input',
180
- value: 'password' !== target.type ? target.value : '*****',
181
- timestamp: Date.now(),
182
- hashId: generateHashId('input', {
183
- ...elementRect
184
- }),
185
- element: target,
186
- inputType: target.type || 'text',
187
- elementRect,
188
- pageInfo: {
189
- width: window.innerWidth,
190
- height: window.innerHeight
191
- }
192
- };
193
- debugLog('Throttled input event:', {
194
- value: inputEvent.value,
195
- timestamp: inputEvent.timestamp,
196
- target: target.tagName,
197
- inputType: target.type
198
- });
199
- this.eventCallback(inputEvent);
174
+ if (this.pendingInputEvent?.element !== target) this.flushPendingInput();
175
+ if (null !== this.inputThrottleTimer) clearTimeout(this.inputThrottleTimer);
176
+ this.pendingInputEvent = {
177
+ type: 'input',
178
+ value: 'password' !== target.type ? target.value : '*****',
179
+ timestamp: Date.now(),
180
+ hashId: generateHashId('input', elementRect),
181
+ element: target,
182
+ inputType: target.type || 'text',
183
+ elementRect,
184
+ pageInfo: {
185
+ width: window.innerWidth,
186
+ height: window.innerHeight
200
187
  }
201
- this.inputThrottleTimer = null;
202
- }, this.inputThrottleDelay);
188
+ };
189
+ this.inputThrottleTimer = window.setTimeout(()=>this.flushPendingInput(), this.inputThrottleDelay);
203
190
  };
191
+ flushPendingInput() {
192
+ if (null !== this.inputThrottleTimer) {
193
+ clearTimeout(this.inputThrottleTimer);
194
+ this.inputThrottleTimer = null;
195
+ }
196
+ if (this.pendingInputEvent) {
197
+ const inputEvent = this.pendingInputEvent;
198
+ this.pendingInputEvent = null;
199
+ this.eventCallback(inputEvent);
200
+ }
201
+ }
204
202
  checkLabelClick(target) {
205
203
  let isLabelClick = false;
206
204
  let labelInfo;
@@ -23,6 +23,7 @@ export declare class EventRecorder {
23
23
  private scrollThrottleDelay;
24
24
  private inputThrottleTimer;
25
25
  private inputThrottleDelay;
26
+ private pendingInputEvent;
26
27
  private lastViewportScroll;
27
28
  private sessionId;
28
29
  private mutationObserver;
@@ -33,6 +34,7 @@ export declare class EventRecorder {
33
34
  private handleClick;
34
35
  private handleScroll;
35
36
  private handleInput;
37
+ private flushPendingInput;
36
38
  private checkLabelClick;
37
39
  isActive(): boolean;
38
40
  optimizeEvent(event: RecordedEvent, events: RecordedEvent[]): RecordedEvent[];
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../src/recorder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAkCvE,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAGxD,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAgC3D,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,kBAAkB,CAAiC;IAC3D,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAAiC;gBAE7C,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM;IAM3D,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB;IAetE,KAAK,IAAI,IAAI;IA6Bb,IAAI,IAAI,IAAI;IAyBZ,OAAO,CAAC,WAAW,CAwCjB;IAGF,OAAO,CAAC,YAAY,CA0DlB;IAGF,OAAO,CAAC,WAAW,CAiDjB;IAGF,OAAO,CAAC,eAAe;IAwCvB,QAAQ,IAAI,OAAO;IAIZ,aAAa,CAClB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,aAAa,EAAE,GACtB,aAAa,EAAE;CA6FnB;AAGD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,GACnB,mBAAmB,CAerB;AAGD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EAAE,GACtB,mBAAmB,EAAE,CAEvB"}
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../src/recorder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAkCvE,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAGxD,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAgC3D,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,kBAAkB,CAAiC;IAC3D,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAAiC;gBAE7C,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM;IAM3D,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB;IAetE,KAAK,IAAI,IAAI;IA6Bb,IAAI,IAAI,IAAI;IAsBZ,OAAO,CAAC,WAAW,CA0CjB;IAGF,OAAO,CAAC,YAAY,CA0DlB;IAGF,OAAO,CAAC,WAAW,CAuCjB;IAEF,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,eAAe;IAwCvB,QAAQ,IAAI,OAAO;IAIZ,aAAa,CAClB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,aAAa,EAAE,GACtB,aAAa,EAAE;CA6FnB;AAGD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,GACnB,mBAAmB,CAerB;AAGD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EAAE,GACtB,mBAAmB,EAAE,CAEvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/recorder-ui",
3
- "version": "1.17.3",
3
+ "version": "1.17.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/midscene.git",
@@ -29,7 +29,7 @@
29
29
  "antd": "^5.21.6",
30
30
  "dayjs": "^1.11.11",
31
31
  "react-dom": "18.3.1",
32
- "@midscene/shared": "1.17.3"
32
+ "@midscene/shared": "1.17.4"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": "18.3.1",