11var utils = require ( './utils' ) ;
22
3+ var MAX_URL_LENGTH = 2000 ;
4+ var hasCors = 'withCredentials' in new XMLHttpRequest ( ) ;
5+
6+ function sendEvents ( eventsUrl , events , sync ) {
7+ var src = eventsUrl + '?d=' + utils . base64URLEncode ( JSON . stringify ( events ) ) ;
8+
9+ var send = function ( onDone ) {
10+ // Detect browser support for CORS
11+ if ( hasCors ) {
12+ /* supports cross-domain requests */
13+ var xhr = new XMLHttpRequest ( ) ;
14+ xhr . open ( 'GET' , src , ! sync ) ;
15+
16+ if ( ! sync ) {
17+ xhr . addEventListener ( 'load' , onDone ) ;
18+ }
19+
20+ xhr . send ( ) ;
21+ } else {
22+ var img = new Image ( ) ;
23+
24+ if ( ! sync ) {
25+ img . addEventListener ( 'load' , onDone ) ;
26+ }
27+
28+ img . src = src ;
29+ }
30+ }
31+
32+ if ( sync ) {
33+ send ( ) ;
34+ } else {
35+ return new Promise ( function ( resolve ) {
36+ send ( resolve ) ;
37+ } ) ;
38+ }
39+ }
40+
341function EventProcessor ( eventsUrl , eventSerializer ) {
442 var processor = { } ;
543 var queue = [ ] ;
@@ -8,63 +46,35 @@ function EventProcessor(eventsUrl, eventSerializer) {
846 processor . enqueue = function ( event ) {
947 queue . push ( event ) ;
1048 } ;
11-
49+
1250 processor . flush = function ( user , sync ) {
13- var maxLength = 2000 - eventsUrl . length ;
14- var data = [ ] ;
15-
51+ var finalSync = sync === undefined ? false : sync ;
52+ var serializedQueue = eventSerializer . serialize_events ( queue ) ;
53+ var chunks ;
54+ var results = [ ] ;
55+
1656 if ( ! user ) {
1757 if ( initialFlush ) {
1858 console && console . warn && console . warn ( 'Be sure to call `identify` in the LaunchDarkly client: http://docs.launchdarkly.com/docs/running-an-ab-test#include-the-client-side-snippet' ) ;
1959 }
20- return false ;
60+ return Promise . resolve ( ) ;
2161 }
2262
2363 initialFlush = false ;
24- while ( maxLength > 0 && queue . length > 0 ) {
25- var event = queue . pop ( ) ;
26- event . user = user ;
27- maxLength = maxLength - utils . base64URLEncode ( JSON . stringify ( event ) ) . length ;
28- // If we are over the max size, put this one back on the queue
29- // to try in the next round, unless this event alone is larger
30- // than the limit, in which case, screw it, and try it anyway.
31- if ( maxLength < 0 && data . length > 0 ) {
32- queue . push ( event ) ;
33- } else {
34- data . push ( event ) ;
35- }
64+
65+ if ( serializedQueue . length === 0 ) {
66+ return Promise . resolve ( ) ;
3667 }
68+
69+ chunks = utils . chunkUserEventsForUrl ( MAX_URL_LENGTH - eventsUrl . length , serializedQueue ) ;
3770
38- if ( data . length > 0 ) {
39- data = eventSerializer . serialize_events ( data ) ;
40- var src = eventsUrl + '?d=' + utils . base64URLEncode ( JSON . stringify ( data ) ) ;
41- //Detect browser support for CORS
42- if ( 'withCredentials' in new XMLHttpRequest ( ) ) {
43- /* supports cross-domain requests */
44- var xhr = new XMLHttpRequest ( ) ;
45- xhr . open ( 'GET' , src , ! sync ) ;
46- xhr . send ( ) ;
47- } else {
48- var img = new Image ( ) ;
49- img . src = src ;
50- }
71+ for ( var i = 0 ; i < chunks . length ; i ++ ) {
72+ results . push ( sendEvents ( eventsUrl , chunks [ i ] , finalSync ) ) ;
5173 }
5274
53- // if the queue is not empty, call settimeout to flush it again
54- // with a 0 timeout (stack-less recursion)
55- // Or, just recursively call flush_queue with the remaining elements
56- // if we're doing this on unload
57- if ( queue . length > 0 ) {
58- if ( sync ) {
59- processor . flush ( user , sync ) ;
60- }
61- else {
62- setTimeout ( function ( ) {
63- processor . flush ( user ) ;
64- } , 0 ) ;
65- }
66- }
67- return false ;
75+ queue = [ ] ;
76+
77+ return sync ? Promise . resolve ( ) : Promise . all ( results ) ;
6878 } ;
6979
7080 return processor ;
0 commit comments