push dispatches with Set.forEach over the live listener set:
// packages/core/src/helpers/createEventEmitter/createEventEmitter.ts:19-22
const push = <Event extends keyof Events>(event: Event, data: Events[Event]) => {
const eventListeners = listeners.get(event as string);
eventListeners?.forEach((listener) => listener(data));
};
A listener that throws kills the loop, so every listener after it never fires and the exception surfaces at the push call site. And Set.forEach visits entries added during iteration, so subscribing inside a listener delivers the event being dispatched to the new listener.
Two things are also missing: once, and a way to drop all listeners for an event. And useSubscribe calls setData on every push, so a subscriber that only wants a side effect re-renders anyway.
What needs to be done
- Dispatch over a snapshot and isolate listener errors so one throwing subscriber does not stop the rest. This also means a listener removed mid dispatch now gets the in flight event, which matches Node and the DOM but is a behavior change.
- Add
once(event, listener) returning an unsubscribe function.
- Add
reset(event) and reset().
- Split off
useSubscribeEffect for subscribers that only want a side effect.
- Key the listener map by
keyof Events instead of string, which removes the four as string casts.
- Declare the
EventEmitterApi<Events> type the JSDoc already references but that does not exist, the way createStore does with StoreApi.
- Update the tests, the demo, and the JSDoc example.
pushdispatches withSet.forEachover the live listener set:A listener that throws kills the loop, so every listener after it never fires and the exception surfaces at the
pushcall site. AndSet.forEachvisits entries added during iteration, so subscribing inside a listener delivers the event being dispatched to the new listener.Two things are also missing:
once, and a way to drop all listeners for an event. AnduseSubscribecallssetDataon every push, so a subscriber that only wants a side effect re-renders anyway.What needs to be done
once(event, listener)returning an unsubscribe function.reset(event)andreset().useSubscribeEffectfor subscribers that only want a side effect.keyof Eventsinstead ofstring, which removes the fouras stringcasts.EventEmitterApi<Events>type the JSDoc already references but that does not exist, the waycreateStoredoes withStoreApi.