@@ -5,7 +5,6 @@ class EventSource {
5
5
CLOSED = 2 ;
6
6
7
7
constructor ( url , options = { } ) {
8
- this . interval = options . pollingInterval || 5000 ;
9
8
this . lastEventId = null ;
10
9
this . lastIndexProcessed = 0 ;
11
10
this . eventType = undefined ;
@@ -19,11 +18,13 @@ class EventSource {
19
18
} ;
20
19
21
20
this . method = options . method || 'GET' ;
22
- this . timeout = options . timeOut || 0 ;
21
+ this . timeout = options . timeout ?? 0 ;
22
+ this . timeoutBeforeConnection = options . timeoutBeforeConnection ?? 500 ;
23
+ this . withCredentials = options . withCredentials || false ;
23
24
this . headers = options . headers || { } ;
24
25
this . body = options . body || undefined ;
25
26
this . debug = options . debug || false ;
26
- this . timeoutBeforeConnection = options . timeoutBeforeConnection ?? 500 ;
27
+ this . interval = options . pollingInterval ?? 5000 ;
27
28
28
29
this . _xhr = null ;
29
30
this . _pollTimer = null ;
@@ -38,13 +39,16 @@ class EventSource {
38
39
this . url = url ;
39
40
}
40
41
41
- this . _pollAgain ( this . timeoutBeforeConnection ) ;
42
+ this . _pollAgain ( this . timeoutBeforeConnection , true ) ;
42
43
}
43
44
44
- _pollAgain ( time ) {
45
- this . _pollTimer = setTimeout ( ( ) => {
46
- this . open ( ) ;
47
- } , time ) ;
45
+ _pollAgain ( time , allowZero ) {
46
+ if ( time > 0 || allowZero ) {
47
+ this . _logDebug ( `[EventSource] Will open new connection in ${ time } ms.` ) ;
48
+ this . _pollTimer = setTimeout ( ( ) => {
49
+ this . open ( ) ;
50
+ } , time ) ;
51
+ }
48
52
}
49
53
50
54
open ( ) {
@@ -55,6 +59,10 @@ class EventSource {
55
59
this . _xhr = new XMLHttpRequest ( ) ;
56
60
this . _xhr . open ( this . method , this . url , true ) ;
57
61
62
+ if ( this . withCredentials ) {
63
+ this . _xhr . withCredentials = true ;
64
+ }
65
+
58
66
if ( this . headers ) {
59
67
for ( const [ key , value ] of Object . entries ( this . headers ) ) {
60
68
this . _xhr . setRequestHeader ( key , value ) ;
@@ -72,13 +80,13 @@ class EventSource {
72
80
this . _xhr . timeout = this . timeout ;
73
81
74
82
this . _xhr . onreadystatechange = ( ) => {
83
+ if ( this . status === this . CLOSED ) {
84
+ return ;
85
+ }
86
+
75
87
const xhr = this . _xhr ;
76
88
77
- if ( this . debug ) {
78
- console . debug (
79
- `[EventSource][onreadystatechange] ReadyState: ${ xhr . readyState } , status: ${ xhr . status } `
80
- ) ;
81
- }
89
+ this . _logDebug ( `[EventSource][onreadystatechange] ReadyState: ${ xhr . readyState } , status: ${ xhr . status } ` ) ;
82
90
83
91
if ( ! [ XMLHttpRequest . DONE , XMLHttpRequest . LOADING ] . includes ( xhr . readyState ) ) {
84
92
return ;
@@ -93,38 +101,31 @@ class EventSource {
93
101
this . _handleEvent ( xhr . responseText || '' ) ;
94
102
95
103
if ( xhr . readyState === XMLHttpRequest . DONE ) {
96
- if ( this . debug ) {
97
- console . debug (
98
- '[EventSource][onreadystatechange][DONE] Operation done. Reconnecting...'
99
- ) ;
100
- }
101
- this . _pollAgain ( this . interval ) ;
102
- }
103
- } else if ( this . status !== this . CLOSED ) {
104
- if ( this . _xhr . status !== 0 ) {
105
- this . dispatch ( 'error' , {
106
- type : 'error' ,
107
- message : xhr . responseText ,
108
- xhrStatus : xhr . status ,
109
- xhrState : xhr . readyState ,
110
- } ) ;
104
+ this . _logDebug ( '[EventSource][onreadystatechange][DONE] Operation done.' ) ;
105
+ this . _pollAgain ( this . interval , false ) ;
111
106
}
107
+ } else if ( xhr . status !== 0 ) {
108
+ this . status = this . ERROR ;
109
+ this . dispatch ( 'error' , {
110
+ type : 'error' ,
111
+ message : xhr . responseText ,
112
+ xhrStatus : xhr . status ,
113
+ xhrState : xhr . readyState ,
114
+ } ) ;
112
115
113
- if ( [ XMLHttpRequest . DONE , XMLHttpRequest . UNSENT ] . includes ( xhr . readyState ) ) {
114
- if ( this . debug ) {
115
- console . debug (
116
- '[EventSource][onreadystatechange][ERROR] Response status error. Reconnecting...'
117
- ) ;
118
- }
119
-
120
- this . _pollAgain ( this . interval ) ;
116
+ if ( xhr . readyState === XMLHttpRequest . DONE ) {
117
+ this . _logDebug ( '[EventSource][onreadystatechange][ERROR] Response status error.' ) ;
118
+ this . _pollAgain ( this . interval , false ) ;
121
119
}
122
120
}
123
121
} ;
124
122
125
- this . _xhr . onerror = ( e ) => {
126
- this . status === this . ERROR ;
123
+ this . _xhr . onerror = ( ) => {
124
+ if ( this . status === this . CLOSED ) {
125
+ return ;
126
+ }
127
127
128
+ this . status = this . ERROR ;
128
129
this . dispatch ( 'error' , {
129
130
type : 'error' ,
130
131
message : this . _xhr . responseText ,
@@ -142,10 +143,7 @@ class EventSource {
142
143
if ( this . timeout > 0 ) {
143
144
setTimeout ( ( ) => {
144
145
if ( this . _xhr . readyState === XMLHttpRequest . LOADING ) {
145
- this . dispatch ( 'error' , {
146
- type : 'timeout' ,
147
- } ) ;
148
-
146
+ this . dispatch ( 'error' , { type : 'timeout' } ) ;
149
147
this . close ( ) ;
150
148
}
151
149
} , this . timeout ) ;
@@ -160,6 +158,12 @@ class EventSource {
160
158
}
161
159
}
162
160
161
+ _logDebug ( ...msg ) {
162
+ if ( this . debug ) {
163
+ console . debug ( ...msg ) ;
164
+ }
165
+ }
166
+
163
167
_handleEvent ( response ) {
164
168
const parts = response . substr ( this . lastIndexProcessed ) . split ( '\n' ) ;
165
169
this . lastIndexProcessed = response . lastIndexOf ( '\n\n' ) + 2 ;
@@ -205,7 +209,7 @@ class EventSource {
205
209
if ( this . eventHandlers [ type ] === undefined ) {
206
210
this . eventHandlers [ type ] = [ ] ;
207
211
}
208
-
212
+
209
213
this . eventHandlers [ type ] . push ( listener ) ;
210
214
}
211
215
0 commit comments