11import { invariant } from 'outvariant'
2+ import { Emitter , type InferListenerType } from 'rettime'
23import { OperationTypeNode } from 'graphql'
34import type {
45 WebSocketConnectionData ,
@@ -372,9 +373,9 @@ export function createGraphQLSubscriptionHandler(
372373 }
373374}
374375
375- interface GraphQLServerSubscriptionEventMap {
376- connection_ack : Event
377- next : MessageEvent < GraphQLWebSocketNextMessage >
376+ type GraphQLServerSubscriptionEventMap = {
377+ connection_ack : never
378+ next : [ GraphQLWebSocketNextMessage ]
378379}
379380
380381/**
@@ -384,7 +385,7 @@ interface GraphQLServerSubscriptionEventMap {
384385class GraphQLServerSubscription {
385386 protected readonly server : WebSocketServerConnection
386387
387- private eventTarget : EventTarget
388+ private emitter : Emitter < GraphQLServerSubscriptionEventMap >
388389 private abortController : AbortController
389390
390391 constructor (
@@ -393,7 +394,10 @@ class GraphQLServerSubscription {
393394 message : GraphQLWebSocketSubscribeMessage
394395 } ,
395396 ) {
396- this . eventTarget = new EventTarget ( )
397+ this . emitter = new Emitter ( )
398+
399+ // An abort controller responsible for removing the server event listeners
400+ // once the subscription is unsubscribed.
397401 this . abortController = new AbortController ( )
398402 this . server = args . server
399403
@@ -425,7 +429,7 @@ class GraphQLServerSubscription {
425429
426430 switch ( message . type ) {
427431 case 'connection_ack' : {
428- this . eventTarget . dispatchEvent ( new Event ( 'connection_ack' ) )
432+ this . emitter . emit ( 'connection_ack' )
429433 break
430434 }
431435
@@ -434,11 +438,7 @@ class GraphQLServerSubscription {
434438 * @fixme This isn't the same `event` from the server
435439 * so calling `event.preventDefault()` won't prevent anything.
436440 */
437- this . eventTarget . dispatchEvent (
438- new MessageEvent ( 'next' , {
439- data : message ,
440- } ) ,
441- )
441+ this . emitter . emit ( 'next' , message )
442442 break
443443 }
444444 }
@@ -450,20 +450,21 @@ class GraphQLServerSubscription {
450450 }
451451
452452 public addEventListener <
453- EventType extends keyof GraphQLServerSubscriptionEventMap ,
454- > (
455- event : EventType ,
456- listener : ( event : GraphQLServerSubscriptionEventMap [ EventType ] ) => void ,
457- ) {
458- this . eventTarget . addEventListener (
459- event ,
460- { handleEvent : listener } ,
461- { signal : this . abortController . signal } ,
462- )
453+ Type extends keyof GraphQLServerSubscriptionEventMap & string ,
454+ > ( event : Type , listener : InferListenerType < typeof this . emitter , Type > ) {
455+ this . emitter . on ( event , listener , {
456+ signal : this . abortController . signal ,
457+ } )
463458 }
464459
465460 public unsubscribe ( ) : void {
461+ // Remove internal listeners on the server object.
466462 this . abortController . abort ( )
463+
464+ // Remove user-defined listeners.
465+ this . emitter . removeAllListeners ( )
466+
467+ // Serve the WebSocket connection.
467468 this . server . close ( )
468469 }
469470}
0 commit comments