diff --git a/src/eventsource.spec.ts b/src/eventsource.spec.ts index da79f3c..7da23da 100644 --- a/src/eventsource.spec.ts +++ b/src/eventsource.spec.ts @@ -45,7 +45,7 @@ describe('EventSource', () => { ev.onopen = () => done(); }); - it('allows for a custom fetch implementation to be used', (done) => { + it('allows for a custom fetch implementation to be via extraOptions used', (done) => { mockChunks(); const fetchFn = jest.fn((input, init?) => { @@ -58,7 +58,29 @@ describe('EventSource', () => { disableRetry: true, }, { - inputFetch: fetchFn, + fetchInput: fetchFn, + }, + ); + + ev.onopen = (event) => { + expect(event).toBeInstanceOf(Event); + expect(fetchFn).toHaveBeenCalled(); + done(); + }; + }); + + it('allows for a custom fetch implementation to be via extraOptions used', (done) => { + mockChunks(); + + const fetchFn = jest.fn((input, init?) => { + return globalThis.fetch(input, init); + }) as typeof fetch; + + const ev = new EventSource( + 'http://localhost/sse', + { + disableRetry: true, + fetch: fetchFn, }, ); diff --git a/src/eventsource.ts b/src/eventsource.ts index 0dc0ff6..6a5fef8 100644 --- a/src/eventsource.ts +++ b/src/eventsource.ts @@ -4,12 +4,42 @@ import { EventSourceMessage, getLines, getMessages, readChunks } from './parse'; const ContentTypeEventStream = 'text/event-stream'; export type EventSourceOptions = { + /** + * Disables connection retrying. + */ disableRetry?: boolean; + + /** + * Delay in milliseconds for retrying connection. + */ retry?: number; + + /** + * Disables logging. + */ disableLogger?: boolean; + + /** + * Logger to use for events and errors. Defaults to console. + */ logger?: Logger; + + /** + * Fetch implementation to use for connecting. Defaults to globalThis.fetch + */ + fetch?: typeof fetch; } & Omit; +/** + * @deprecated + */ +export type EventSourceExtraOptions = { + /** + * @deprecated Use {@link EventSourceOptions#fetch} instead + */ + fetchInput?: typeof fetch; +}; + export class CustomEventSource extends EventTarget implements EventSource { // https://html.spec.whatwg.org/multipage/server-sent-events.html#dom-eventsource-url public url: string; @@ -33,6 +63,7 @@ export class CustomEventSource extends EventTarget implements EventSource { | null = null; public readonly options: EventSourceInit & EventSourceOptions; + private readonly extraOptions?: EventSourceExtraOptions; private abortController?: AbortController; private timeoutId: ReturnType | undefined = undefined; private retry: number; @@ -40,17 +71,18 @@ export class CustomEventSource extends EventTarget implements EventSource { private logger?: Logger; - private fetch: typeof fetch; - constructor( url: string | URL, initDict?: EventSourceInit & EventSourceOptions, - { inputFetch } = { inputFetch: globalThis.fetch.bind(globalThis) }, + /** + * @deprecated Use the related options in initDict + */ + extraOptions?: EventSourceExtraOptions, ) { super(); - this.fetch = inputFetch; - this.url = url instanceof URL ? url.toString() : url; this.options = initDict ?? {}; + this.extraOptions = extraOptions; + this.url = url instanceof URL ? url.toString() : url; this.retry = initDict?.retry ?? 5000; if (!this.options.disableLogger) { @@ -99,7 +131,11 @@ export class CustomEventSource extends EventTarget implements EventSource { signal: this.abortController?.signal, }; - const response = await this.fetch(this.url, fetchOptions); + const response = this.options.fetch + ? await this.options.fetch(this.url, fetchOptions) + : this.extraOptions?.fetchInput + ? await this.extraOptions.fetchInput(this.url, fetchOptions) + : await globalThis.fetch(this.url, fetchOptions); // https://html.spec.whatwg.org/multipage/server-sent-events.html#dom-eventsource (Step 15) if (response.status !== 200) {