Skip to content

🧊 feat: fix createEventEmitter dispatch, add once and reset - #506

Open
ashenoooone wants to merge 1 commit into
siberiacancode:mainfrom
ashenoooone:feat/create-event-emitter
Open

🧊 feat: fix createEventEmitter dispatch, add once and reset#506
ashenoooone wants to merge 1 commit into
siberiacancode:mainfrom
ashenoooone:feat/create-event-emitter

Conversation

@ashenoooone

Copy link
Copy Markdown
Contributor

Fixes #505

push dispatched with Set.forEach over the live listener set. A listener that threw killed the loop, so every listener registered after it never fired and the exception surfaced at the push call site instead of staying with the broken subscriber. Set.forEach also visits entries added during iteration, so calling subscribe inside a listener delivered the event being dispatched to the new listener. Dispatch now runs over a snapshot with each call isolated, and a listener error is rethrown through queueMicrotask so it still reaches the global handler without breaking delivery.

Added once, which unsubscribes before invoking the listener so that a throwing one does not stay subscribed forever, and which can be cancelled either by the returned function or by unsubscribe with the original reference, matching Node's EventEmitter and addEventListener with { once: true }. Added reset(event) and reset(). Split off useSubscribeEffect for subscribers that only want a side effect, since useSubscribe calls setData on every push and re-renders either way. Keyed the listener map by keyof Events instead of string, which drops the four as string casts, and declared the EventEmitterApi<Events> type that the JSDoc already pointed at but that did not exist, the way createStore does with StoreApi.

One behavior change worth calling out: a listener removed mid dispatch now receives the in flight event, where before it did not. That matches Node and the DOM and falls out of the snapshot fix. 14 tests cover the new behavior. The demo is left alone here, since it would have to use API that is not published yet and the docs site builds demos against the released package rather than the workspace one.

…пшоту, once и reset

Падающий листенер обрывал forEach, подписчики после него не получали
событие, а исключение всплывало в месте вызова push. Set.forEach ещё и
обходит записи, добавленные во время итерации, поэтому подписка внутри
листенера получала текущее событие.

- push идёт по копии, ошибка листенера уходит в queueMicrotask
- once с отпиской, снимается и по исходной ссылке, как в Node
- reset для одного события и для всех
- useSubscribeEffect для подписчиков без ререндера
- мапа по keyof Events вместо string, убраны четыре as string
- объявлен EventEmitterApi, на который уже ссылался JSDoc

Листенер, снятый во время рассылки, теперь получает событие в полёте,
как в Node и DOM. Это изменение поведения.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant