1
1
import { Subject } from '../../Subject.js' ;
2
2
import { Subscriber , Observable , Subscription , operate } from '../../Observable.js' ;
3
- import { ReplaySubject } from '../../ReplaySubject.js' ;
4
- import { Observer , NextObserver } from '../../types.js' ;
3
+ import { NextObserver } from '../../types.js' ;
5
4
6
5
/**
7
6
* WebSocketSubjectConfig is a plain Object that allows us to make our
@@ -158,7 +157,13 @@ export class WebSocketSubject<T> extends Subject<T> {
158
157
159
158
private _socket : WebSocket | null = null ;
160
159
161
- private _input : Observer < T > ;
160
+ private _inputBuffer : T [ ] = [ ] ;
161
+
162
+ private _hasError = false ;
163
+
164
+ private _error : any ;
165
+
166
+ private _isComplete = false ;
162
167
163
168
constructor ( urlConfigOrSource : string | WebSocketSubjectConfig < T > ) {
164
169
super ( ) ;
@@ -177,13 +182,15 @@ export class WebSocketSubject<T> extends Subject<T> {
177
182
}
178
183
179
184
this . _output = new Subject < T > ( ) ;
180
- this . _input = new ReplaySubject ( ) ;
181
185
}
182
186
183
187
private _resetState ( ) {
184
188
this . _socket = null ;
185
- this . _input = new ReplaySubject ( ) ;
186
189
this . _output = new Subject < T > ( ) ;
190
+ this . _inputBuffer = [ ] ;
191
+ this . _hasError = false ;
192
+ this . _isComplete = false ;
193
+ this . _error = null ;
187
194
}
188
195
189
196
/**
@@ -250,44 +257,14 @@ export class WebSocketSubject<T> extends Subject<T> {
250
257
251
258
this . _config . openObserver ?. next ( evt ) ;
252
259
253
- const previousInput = this . _input ;
254
-
255
- // We switch over now to passthrough all messages directly to the
256
- // to the socket, where previously we were queuing them up with
257
- // a ReplaySubject.
258
- this . _input = new Subscriber < T > ( {
259
- next : ( x ) => {
260
- if ( socket ! . readyState === 1 ) {
261
- try {
262
- socket ! . send ( this . _config . serializer ! ( x ) ) ;
263
- } catch ( e ) {
264
- this . _input . error ( e ) ;
265
- }
266
- }
267
- } ,
268
- error : ( err : any ) => {
269
- this . _config . closingObserver ?. next ( undefined ) ;
270
- if ( err ?. code ) {
271
- socket ! . close ( err . code , err . reason ) ;
272
- } else {
273
- _output . error ( new TypeError ( WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT ) ) ;
274
- }
275
- this . _resetState ( ) ;
276
- } ,
277
- complete : ( ) => {
278
- this . _config . closingObserver ?. next ( undefined ) ;
279
- socket ! . close ( ) ;
280
- this . _resetState ( ) ;
281
- } ,
282
- } ) ;
260
+ while ( this . _inputBuffer . length > 0 ) {
261
+ this . next ( this . _inputBuffer . shift ( ) ! ) ;
262
+ }
283
263
284
- // If the _input was a ReplaySubject before, when we
285
- // subscribe right now, it will synchronously emit all
286
- // of the buffered values.
287
- if ( previousInput instanceof ReplaySubject ) {
288
- // Note that since `_input` is a `Subscriber`, this will
289
- // automatically wire up the subscription.
290
- previousInput . subscribe ( this . _input ) ;
264
+ if ( this . _hasError ) {
265
+ this . error ( this . _error ) ;
266
+ } else if ( this . _isComplete ) {
267
+ this . complete ( ) ;
291
268
}
292
269
} ;
293
270
@@ -322,15 +299,46 @@ export class WebSocketSubject<T> extends Subject<T> {
322
299
}
323
300
324
301
next ( value : T ) {
325
- this . _input . next ( value ) ;
302
+ if ( this . _socket ?. readyState !== 1 ) {
303
+ this . _inputBuffer . push ( value ) ;
304
+ } else {
305
+ try {
306
+ this . _socket . send ( this . _config . serializer ! ( value ) ) ;
307
+ } catch ( err : any ) {
308
+ this . _config . closingObserver ?. next ( undefined ) ;
309
+ if ( err ?. code ) {
310
+ this . _socket . close ( err . code , err . reason ) ;
311
+ } else {
312
+ this . _output . error ( new TypeError ( WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT ) ) ;
313
+ }
314
+ this . _resetState ( ) ;
315
+ }
316
+ }
326
317
}
327
318
328
319
error ( err : any ) {
329
- this . _input . error ( err ) ;
320
+ if ( this . _socket ?. readyState === 1 ) {
321
+ this . _config . closingObserver ?. next ( undefined ) ;
322
+ if ( err ?. code ) {
323
+ this . _socket ?. close ( err . code , err . reason ) ;
324
+ } else {
325
+ this . _output . error ( new TypeError ( WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT ) ) ;
326
+ }
327
+ this . _resetState ( ) ;
328
+ } else {
329
+ this . _hasError = true ;
330
+ this . _error = err ;
331
+ }
330
332
}
331
333
332
334
complete ( ) {
333
- this . _input . complete ( ) ;
335
+ if ( this . _socket ?. readyState === 1 ) {
336
+ this . _config . closingObserver ?. next ( undefined ) ;
337
+ this . _socket . close ( ) ;
338
+ this . _resetState ( ) ;
339
+ } else {
340
+ this . _isComplete = true ;
341
+ }
334
342
}
335
343
336
344
/** @internal */
0 commit comments