diff --git a/source/event-emitter.ts b/source/event-emitter.ts index da22964..d369166 100644 --- a/source/event-emitter.ts +++ b/source/event-emitter.ts @@ -1,6 +1,6 @@ export type EventMap = Record; -type Listener = (detail: T) => void; +type Listener = (detail: Readonly) => void; /** * Internally permits listeners for individual event payloads to be stored @@ -72,7 +72,7 @@ export class EventEmitter { * @returns An off callback that can be called to stop listening for events. */ once(type: K, listener: Listener, debounceMilliseconds?: number): OffCallback { - const wrappedListener: Listener = (detail: T[K]) => { + const wrappedListener: Listener = (detail: Readonly) => { this.off(type, listener); listener(detail); }; @@ -131,9 +131,12 @@ export class EventEmitter { const listeners = this.listeners.get(type); if (!listeners) return false; + // Freeze the payload to make it readonly. + const readonlyPayload = Object.freeze(payload); + // Emit the event to all listeners. listeners.forEach((entry) => { - entry.wrappedListener(payload); + entry.wrappedListener(readonlyPayload); }); // Return true if there are listeners for the event, false otherwise. @@ -154,13 +157,13 @@ export class EventEmitter { * @param timeoutMs - The timeout in milliseconds. * @returns The event payload. */ - async waitFor(type: K, predicate: (payload: T[K]) => boolean, timeoutMs?: number): Promise { + async waitFor(type: K, predicate: (payload: Readonly) => boolean, timeoutMs?: number): Promise> { // Create a promise to wait for the event to be emitted. return new Promise((resolve, reject) => { let timeoutId: ReturnType | undefined; // Create a listener function. - const listener = (payload: T[K]): void => { + const listener = (payload: Readonly): void => { if (predicate(payload)) { // Clean up this.off(type, listener); @@ -195,7 +198,7 @@ export class EventEmitter { // Create a timeout variable. let timeout: ReturnType; - return (detail: T[K]) => { + return (detail: Readonly) => { // If a debounce timer is already pending, clear it before scheduling the next one. if (timeout !== undefined) { clearTimeout(timeout);