1111 * and limitations under the License.
1212 */
1313import { ConsoleLogger as Logger } from '@aws-amplify/core' ;
14+ import { LOG_TYPE } from '@aws-amplify/core/lib/Logger' ;
1415import { ClickstreamContext } from './ClickstreamContext' ;
16+ import { Event } from './Event' ;
1517import { NetRequest } from '../network/NetRequest' ;
1618import { AnalyticsEvent , SendMode } from '../types' ;
1719import { StorageUtil } from '../util/StorageUtil' ;
@@ -21,6 +23,7 @@ const logger = new Logger('EventRecorder');
2123export class EventRecorder {
2224 clickstream : ClickstreamContext ;
2325 bundleSequenceId : number ;
26+ isFlushingEvents : boolean ;
2427
2528 constructor ( clickstream : ClickstreamContext ) {
2629 this . clickstream = clickstream ;
@@ -29,33 +32,43 @@ export class EventRecorder {
2932
3033 record ( event : AnalyticsEvent ) {
3134 if ( this . clickstream . configuration . isLogEvents ) {
32- logger . level = Logger . LOG_LEVEL . DEBUG ;
35+ logger . level = LOG_TYPE . DEBUG ;
3336 logger . debug (
3437 `Logged event ${ event . event_type } , event attributes:\n
3538 ${ JSON . stringify ( event . attributes ) } `
3639 ) ;
3740 }
38- if ( this . clickstream . configuration . sendMode === SendMode . Immediate ) {
39- const eventsJson = JSON . stringify ( [ event ] ) ;
40- NetRequest . sendRequest (
41- eventsJson ,
42- this . clickstream ,
43- this . bundleSequenceId
44- ) . then ( result => {
45- if ( result ) {
46- logger . debug ( 'Event send success' ) ;
47- } else {
48- StorageUtil . saveFailedEvent ( event ) ;
41+ switch ( this . clickstream . configuration . sendMode ) {
42+ case SendMode . Immediate :
43+ this . sendEventImmediate ( event ) ;
44+ break ;
45+ case SendMode . Batch :
46+ if ( ! StorageUtil . saveEvent ( event ) ) {
47+ this . sendEventImmediate ( event ) ;
4948 }
50- } ) ;
51- this . plusSequenceId ( ) ;
5249 }
5350 }
5451
52+ sendEventImmediate ( event : AnalyticsEvent ) {
53+ const eventsJson = JSON . stringify ( [ event ] ) ;
54+ NetRequest . sendRequest (
55+ eventsJson ,
56+ this . clickstream ,
57+ this . bundleSequenceId
58+ ) . then ( result => {
59+ if ( result ) {
60+ logger . debug ( 'Event send success' ) ;
61+ } else {
62+ StorageUtil . saveFailedEvent ( event ) ;
63+ }
64+ } ) ;
65+ this . plusSequenceId ( ) ;
66+ }
67+
5568 sendFailedEvents ( ) {
5669 const failedEvents = StorageUtil . getFailedEvents ( ) ;
5770 if ( failedEvents . length > 0 ) {
58- const eventsJson = JSON . stringify ( failedEvents ) ;
71+ const eventsJson = failedEvents + Event . Constants . SUFFIX ;
5972 NetRequest . sendRequest (
6073 eventsJson ,
6174 this . clickstream ,
@@ -70,6 +83,66 @@ export class EventRecorder {
7083 }
7184 }
7285
86+ flushEvents ( ) {
87+ if ( this . isFlushingEvents ) {
88+ return ;
89+ }
90+ const [ eventsJson , needsFlushTwice ] = this . getBatchEvents ( ) ;
91+ if ( eventsJson === '' ) {
92+ return ;
93+ }
94+ this . isFlushingEvents = true ;
95+ NetRequest . sendRequest (
96+ eventsJson ,
97+ this . clickstream ,
98+ this . bundleSequenceId ,
99+ NetRequest . BATCH_REQUEST_RETRY_TIMES ,
100+ NetRequest . BATCH_REQUEST_TIMEOUT
101+ ) . then ( result => {
102+ if ( result ) {
103+ StorageUtil . clearEvents ( eventsJson ) ;
104+ }
105+ this . isFlushingEvents = false ;
106+ if ( needsFlushTwice ) {
107+ this . flushEvents ( ) ;
108+ }
109+ } ) ;
110+ this . plusSequenceId ( ) ;
111+ }
112+
113+ getBatchEvents ( ) : [ string , boolean ] {
114+ let allEventsStr = StorageUtil . getAllEvents ( ) ;
115+ if ( allEventsStr === '' ) {
116+ return [ allEventsStr , false ] ;
117+ } else if ( allEventsStr . length <= StorageUtil . MAX_REQUEST_EVENTS_SIZE ) {
118+ return [ allEventsStr + Event . Constants . SUFFIX , false ] ;
119+ } else {
120+ const isOnlyOneEvent =
121+ allEventsStr . lastIndexOf ( Event . Constants . LAST_EVENT_IDENTIFIER ) < 0 ;
122+ const firstEventSize = allEventsStr . indexOf (
123+ Event . Constants . LAST_EVENT_IDENTIFIER
124+ ) ;
125+ if ( isOnlyOneEvent ) {
126+ return [ allEventsStr + Event . Constants . SUFFIX , false ] ;
127+ } else if ( firstEventSize > StorageUtil . MAX_REQUEST_EVENTS_SIZE ) {
128+ allEventsStr = allEventsStr . substring ( 0 , firstEventSize + 1 ) ;
129+ return [ allEventsStr + Event . Constants . SUFFIX , true ] ;
130+ } else {
131+ allEventsStr = allEventsStr . substring (
132+ 0 ,
133+ StorageUtil . MAX_REQUEST_EVENTS_SIZE
134+ ) ;
135+ const endIndex = allEventsStr . lastIndexOf (
136+ Event . Constants . LAST_EVENT_IDENTIFIER
137+ ) ;
138+ return [
139+ allEventsStr . substring ( 0 , endIndex + 1 ) + Event . Constants . SUFFIX ,
140+ true ,
141+ ] ;
142+ }
143+ }
144+ }
145+
73146 plusSequenceId ( ) {
74147 this . bundleSequenceId += 1 ;
75148 StorageUtil . saveBundleSequenceId ( this . bundleSequenceId ) ;
0 commit comments