fix(typed-emitter): clean up empty Set from Map on last off() call#396
Open
Nexory wants to merge 1 commit into
Open
fix(typed-emitter): clean up empty Set from Map on last off() call#396Nexory wants to merge 1 commit into
Nexory wants to merge 1 commit into
Conversation
TypedEmitter.off() removed the handler from the per-event Set but never removed the (now-empty) Set from the handlers Map. In long-lived emitter instances — SSE reconnect loops, hot-reload cycles, anywhere on()/off() cycle repeatedly — the Map accumulated empty Set entries indefinitely. Add a Map.delete(event) call after Set.delete() when set.size === 0, matching the symmetric on() discipline. emit() already guards if (set) so removing the Map entry is behaviourally equivalent to leaving an empty Set behind.
Contributor
|
@Nexory is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
TypedEmitter.off()removes a handler from the per-eventSetbut never deletes the (now-empty)Setfrom thehandlersMap. In long-lived emitter instances — SSE reconnect loops, hot-reload cycles, anywhereon()/off()cycle repeatedly —handlersaccumulates emptySetentries indefinitely, one per distinct event name that was ever subscribed and then fully unsubscribed.The
emit()path already guards against missing Map keys (if (set)), so removing the entry is semantically equivalent to leaving an empty Set behind. Theon()method (lines 10-17) already has the symmetric discipline — it only inserts a Set when needed. This fix mirrors that pattern on the removal side.Source location
packages/vercel-flags-core/src/controller/typed-emitter.tsline 20.Change
5 lines added, 1 modified. No changes to
on(),emit(), or the class shape.Test plan
Added
packages/vercel-flags-core/src/controller/typed-emitter.test.tscovering the basic cleanup contract plus 7 adversarial edge cases:off()off()on never-registered event is a no-opoff()is idempotenton()after fulloff()creates a fresh Setemitdoes not throwemit()after Map-entry removal is a no-op via existing guardVerified locally on HEAD 5cf0950 with vitest 2.1.9.
Full suite output after fix:
Zero regressions.
Notes
on().emit()path unchanged — its existingif (set)guard makes a missing Map entry behaviourally equivalent to an empty Set.