Skip to content

createEventEmitter: dispatch bugs and missing once / reset / side-effect-only subscribe #505

Description

@ashenoooone

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

  1. 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.
  2. Add once(event, listener) returning an unsubscribe function.
  3. Add reset(event) and reset().
  4. Split off useSubscribeEffect for subscribers that only want a side effect.
  5. Key the listener map by keyof Events instead of string, which removes the four as string casts.
  6. Declare the EventEmitterApi<Events> type the JSDoc already references but that does not exist, the way createStore does with StoreApi.
  7. Update the tests, the demo, and the JSDoc example.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions