@@ -113,6 +113,8 @@ export function installHook (target, isIframe = false) {
113
113
Vue : null ,
114
114
enabled : undefined ,
115
115
_buffer : [ ] ,
116
+ _bufferMap : new Map ( ) ,
117
+ _bufferToRemove : new Map ( ) ,
116
118
store : null ,
117
119
initialState : null ,
118
120
storeModules : null ,
@@ -122,13 +124,15 @@ export function installHook (target, isIframe = false) {
122
124
_replayBuffer ( event ) {
123
125
const buffer = this . _buffer
124
126
this . _buffer = [ ]
127
+ this . _bufferMap . clear ( )
128
+ this . _bufferToRemove . clear ( )
125
129
126
130
for ( let i = 0 , l = buffer . length ; i < l ; i ++ ) {
127
- const allArgs = buffer [ i ]
131
+ const allArgs = buffer [ i ] . slice ( 1 )
128
132
allArgs [ 0 ] === event
129
133
// eslint-disable-next-line prefer-spread
130
134
? this . emit . apply ( this , allArgs )
131
- : this . _buffer . push ( allArgs )
135
+ : this . _buffer . push ( buffer [ i ] )
132
136
}
133
137
} ,
134
138
@@ -192,7 +196,16 @@ export function installHook (target, isIframe = false) {
192
196
}
193
197
}
194
198
} else {
195
- this . _buffer . push ( [ event , ...args ] )
199
+ const buffered = [ Date . now ( ) , event , ...args ]
200
+ this . _buffer . push ( buffered )
201
+
202
+ for ( let i = 2 ; i < args . length ; i ++ ) {
203
+ if ( typeof args [ i ] === 'object' && args [ i ] ) {
204
+ // Save by component instance (3rd, 4th or 5th arg)
205
+ this . _bufferMap . set ( args [ i ] , buffered )
206
+ break
207
+ }
208
+ }
196
209
}
197
210
} ,
198
211
@@ -201,18 +214,27 @@ export function installHook (target, isIframe = false) {
201
214
* @param matchArg Given value to match.
202
215
*/
203
216
cleanupBuffer ( matchArg ) {
204
- let wasBuffered = false
205
- this . _buffer = this . _buffer . filter ( item => {
206
- if ( item . some ( arg => arg === matchArg ) ) {
207
- wasBuffered = true
208
- return false
209
- }
210
- return true
211
- } )
212
- return wasBuffered
217
+ const inBuffer = this . _bufferMap . has ( matchArg )
218
+ if ( inBuffer ) {
219
+ // Mark event for removal
220
+ this . _bufferToRemove . set ( this . _bufferMap . get ( matchArg ) , true )
221
+ }
222
+ return inBuffer
223
+ } ,
224
+
225
+ _cleanupBuffer ( ) {
226
+ const now = Date . now ( )
227
+ // Clear buffer events that are older than 10 seconds or marked for removal
228
+ this . _buffer = this . _buffer . filter ( args => ! this . _bufferToRemove . has ( args ) && now - args [ 0 ] < 10_000 )
229
+ this . _bufferToRemove . clear ( )
230
+ this . _bufferMap . clear ( )
213
231
} ,
214
232
}
215
233
234
+ setInterval ( ( ) => {
235
+ hook . _cleanupBuffer ( )
236
+ } , 10_000 )
237
+
216
238
hook . once ( 'init' , Vue => {
217
239
hook . Vue = Vue
218
240
0 commit comments