@@ -28,8 +28,7 @@ import {
2828 InputRTCMediaStats ,
2929 InputRTCMediaTrackClosed ,
3030 InputRTCExternalPeerAttached ,
31- InputRuleEvent ,
32- TimingEvents
31+ InputRuleEvent
3332} from '../../types' ;
3433
3534import { lazyObservablePromise } from '../../util/observable' ;
@@ -114,9 +113,11 @@ type EventType =
114113 | MockttpEventType
115114 | MockRTCEventType ;
116115
117- export type QueuedEvent = ( {
118- [ T in EventType ] : { type : T , event : EventTypesMap [ T ] }
119- } [ EventType ] ) ;
116+ export type QueuedEvent =
117+ | ( { // Received Mockttp event data:
118+ [ T in EventType ] : { type : T , event : EventTypesMap [ T ] }
119+ } [ EventType ] )
120+ | { type : 'queued-callback' , cb : ( ) => void } // Or a callback to run after data is processed
120121
121122type OrphanableQueuedEvent < T extends
122123 | 'response'
@@ -137,6 +138,8 @@ type OrphanableQueuedEvent<T extends
137138 | 'tls-passthrough-closed'
138139> = { type : T , event : EventTypesMap [ T ] } ;
139140
141+ const LARGE_QUEUE_BATCH_SIZE = 1033 ; // Off by 33 for a new ticking UI effect
142+
140143export class EventsStore {
141144
142145 constructor (
@@ -204,8 +207,18 @@ export class EventsStore {
204207 // on request animation frame, so batches get larger and cheaper if
205208 // the frame rate starts to drop.
206209
207- this . eventQueue . forEach ( this . updateFromQueuedEvent ) ;
208- this . eventQueue = [ ] ;
210+ if ( this . eventQueue . length > LARGE_QUEUE_BATCH_SIZE ) {
211+ // If there's a lot of events in the queue (only ever likely to happen
212+ // in an import of a large file) we break it up to keep the UI responsive.
213+ this . eventQueue . slice ( 0 , LARGE_QUEUE_BATCH_SIZE ) . forEach ( this . updateFromQueuedEvent ) ;
214+ this . eventQueue = this . eventQueue . slice ( LARGE_QUEUE_BATCH_SIZE ) ;
215+ setTimeout ( ( ) => {
216+ this . queueEventFlush ( ) ;
217+ } , 10 ) ;
218+ } else {
219+ this . eventQueue . forEach ( this . updateFromQueuedEvent ) ;
220+ this . eventQueue = [ ] ;
221+ }
209222 }
210223
211224 private updateFromQueuedEvent = ( queuedEvent : QueuedEvent ) => {
@@ -263,6 +276,10 @@ export class EventsStore {
263276 return this . addRTCMediaTrackStats ( queuedEvent . event ) ;
264277 case 'media-track-closed' :
265278 return this . markRTCMediaTrackClosed ( queuedEvent . event ) ;
279+
280+ case 'queued-callback' :
281+ queuedEvent . cb ( ) ;
282+ return ;
266283 }
267284 } catch ( e ) {
268285 // It's possible we might fail to parse an input event. This shouldn't happen, but if it
@@ -643,31 +660,18 @@ export class EventsStore {
643660
644661 // We now take each of these input items, and put them on the queue to be added
645662 // to the UI like any other seen request data. Arguably we could call addRequest &
646- // setResponse etc directly, but this is nicer if the UI thread is already under strain.
647-
648- // First, we run through the request & TLS error events together, in order, since these
649- // define the initial event ordering
650- const [ initialEvents , updateEvents ] = _ . partition ( events , ( { type } ) =>
651- type === 'request' ||
652- type === 'websocket-request' ||
653- type === 'tls-client-error'
654- ) ;
655- this . eventQueue . push ( ..._ . sortBy ( initialEvents , ( e ) =>
656- ( e . event as { timingEvents : TimingEvents } ) . timingEvents . startTime
657- ) ) ;
663+ // setResponse etc directly, but this is nicer in case the UI thread is already under strain.
664+ this . eventQueue . push ( ...events ) ;
658665
659- // Then we add everything else (responses & aborts). They just update, so order doesn't matter:
660- this . eventQueue . push ( ...updateEvents ) ;
666+ // After all events are handled, set the required pins:
667+ this . eventQueue . push ( {
668+ type : 'queued-callback' ,
669+ cb : action ( ( ) => pinnedIds . forEach ( ( id ) => {
670+ this . events . find ( e => e . id === id ) ! . pinned = true ;
671+ } ) )
672+ } ) ;
661673
662674 this . queueEventFlush ( ) ;
663-
664- if ( pinnedIds . length ) {
665- // This rAF will be scheduled after the queued flush, so the event should
666- // always be fully imported by this stage:
667- requestAnimationFrame ( action ( ( ) => pinnedIds . forEach ( ( id ) => {
668- this . events . find ( e => e . id === id ) ! . pinned = true ;
669- } ) ) ) ;
670- }
671675 }
672676
673677 @action
0 commit comments