11import { URL } from "url" ;
22import fetch from "@mrbbot/node-fetch" ;
3- import { TypedEventListener , typedEventTarget } from "../helpers " ;
3+ import { Event , EventTarget } from "event-target-shim " ;
44import { Log } from "../log" ;
55import { Context , Module } from "./module" ;
66import { FetchError , Request , Response } from "./standards" ;
@@ -11,7 +11,7 @@ export const responseSymbol = Symbol("response");
1111export const passThroughSymbol = Symbol ( "passThrough" ) ;
1212export const waitUntilSymbol = Symbol ( "waitUntil" ) ;
1313
14- export class FetchEvent extends Event {
14+ export class FetchEvent extends Event < "fetch" > {
1515 [ responseSymbol ] ?: Promise < Response > ;
1616 [ passThroughSymbol ] = false ;
1717 readonly [ waitUntilSymbol ] : Promise < any > [ ] = [ ] ;
@@ -34,7 +34,7 @@ export class FetchEvent extends Event {
3434 }
3535}
3636
37- export class ScheduledEvent extends Event {
37+ export class ScheduledEvent extends Event < "scheduled" > {
3838 readonly [ waitUntilSymbol ] : Promise < any > [ ] = [ ] ;
3939
4040 constructor (
@@ -79,11 +79,11 @@ type EventMap = {
7979 fetch : FetchEvent ;
8080 scheduled : ScheduledEvent ;
8181} ;
82- export class ServiceWorkerGlobalScope extends typedEventTarget < EventMap > ( ) {
82+ export class ServiceWorkerGlobalScope extends EventTarget < EventMap > {
8383 readonly #log: Log ;
8484 readonly #environment: Context ;
8585 readonly #wrappedListeners = new WeakMap <
86- EventListenerOrEventListenerObject ,
86+ EventTarget . EventListener < this , any > ,
8787 EventListener
8888 > ( ) ;
8989 #wrappedError?: Error ;
@@ -116,44 +116,23 @@ export class ServiceWorkerGlobalScope extends typedEventTarget<EventMap>() {
116116 this . dispatchEvent = this . dispatchEvent . bind ( this ) ;
117117 }
118118
119- #wrap( listener : TypedEventListener < Event > | null ) : EventListener | null {
119+ #wrap< T extends keyof EventMap > (
120+ listener ?: EventTarget . EventListener < this, EventMap [ T ] > | null
121+ ) : EventTarget . CallbackFunction < this, EventMap [ T ] > | null | undefined {
120122 // When an event listener throws, we want dispatching to stop and the
121123 // error to be thrown so we can catch it and display a nice error page.
122- // Unfortunately, Node's event target emits uncaught exceptions when a
123- // listener throws, which are tricky to catch without breaking tests (AVA
124- // also registers an uncaught exception handler).
125- //
126- // Node 16.6.0's internal implementation contains this line to throw
127- // uncaught exceptions: `process.nextTick(() => { throw err; });`.
128- // A potential solution would be to monkey-patch `process.nextTick` and call
129- // the callback immediately:
130- //
131- // ```js
132- // const originalNextTick = process.nextTick;
133- // process.nextTick = (callback) => callback();
134- // try {
135- // this.dispatchEvent(event);
136- // } finally {
137- // process.nextTick = originalNextTick;
138- // }
139- // ```
140- //
141- // However, this relies on internal behaviour that may change at any point
142- // and may prevent the EventTarget from doing required clean up. Hence,
143- // we wrap event listeners instead, storing the wrapped versions in a
144- // WeakMap so they can be removed when the original listener is passed to
145- // removeEventListener.
146-
124+ if ( listener === undefined ) return undefined ;
147125 if ( listener === null ) return null ;
148126 const wrappedListeners = this . #wrappedListeners;
149127 let wrappedListener = wrappedListeners . get ( listener ) ;
150128 if ( wrappedListener ) return wrappedListener ;
151129 wrappedListener = ( event ) => {
152130 try {
153131 if ( "handleEvent" in listener ) {
154- listener . handleEvent ( event ) ;
132+ listener . handleEvent ( event as EventMap [ T ] ) ;
155133 } else {
156- listener ( event ) ;
134+ // @ts -expect-error "this" type is definitely correct
135+ listener ( event as EventMap [ T ] ) ;
157136 }
158137 } catch ( error ) {
159138 event . stopImmediatePropagation ( ) ;
@@ -164,20 +143,20 @@ export class ServiceWorkerGlobalScope extends typedEventTarget<EventMap>() {
164143 return wrappedListener ;
165144 }
166145
167- addEventListener < EventType extends keyof EventMap > (
168- type : EventType ,
169- listener : TypedEventListener < EventMap [ EventType ] > | null ,
170- options ?: AddEventListenerOptions | boolean
146+ addEventListener < T extends keyof EventMap > (
147+ type : T ,
148+ listener ?: EventTarget . EventListener < this , EventMap [ T ] > | null ,
149+ options ?: EventTarget . AddOptions | boolean
171150 ) : void {
172- super . addEventListener ( type , this . #wrap( listener as any ) , options ) ;
151+ super . addEventListener ( type , this . #wrap( listener ) , options as any ) ;
173152 }
174153
175- removeEventListener < EventType extends keyof EventMap > (
176- type : EventType ,
177- listener : TypedEventListener < EventMap [ EventType ] > | null ,
178- options ?: EventListenerOptions | boolean
154+ removeEventListener < T extends string & keyof EventMap > (
155+ type : T ,
156+ listener ?: EventTarget . EventListener < this , EventMap [ T ] > | null ,
157+ options ?: EventTarget . Options | boolean
179158 ) : void {
180- super . removeEventListener ( type , this . #wrap( listener as any ) , options ) ;
159+ super . removeEventListener ( type , this . #wrap( listener ) , options as any ) ;
181160 }
182161
183162 dispatchEvent ( event : Event ) : boolean {
0 commit comments