Skip to content

Fix(menu): submenu machine.subscribe accumulation#44

Merged
karim-semmoud merged 4 commits into
mainfrom
fix/menu-submenu-subscribe-leak
Jun 1, 2026
Merged

Fix(menu): submenu machine.subscribe accumulation#44
karim-semmoud merged 4 commits into
mainfrom
fix/menu-submenu-subscribe-leak

Conversation

@karim-semmoud

Copy link
Copy Markdown
Member

Summary

Fixes a memory and performance bug in nested menus where machine.subscribe callbacks accumulated on every LiveView update.

renderSubmenuTriggers() subscribed to parent and child Zag machines on each call without unsubscribing. The menu hook calls wireSubmenuTriggersDeep() on mount and on every updated(), so subscriber count grew with each server re-render. That caused duplicate DOM updates, stale closures, and unnecessary work.

Also fixes a related race: nested menu wiring ran in setTimeout(..., 0) with no cancellation, so wiring could run after the hook was destroyed on fast navigation.

Changes

assets/components/menu.ts
Track submenu trigger unsubscribe handles in submenuTriggerUnsubs
Tear down existing subscriptions at the start of renderSubmenuTriggers()
Clear all submenu subscriptions in destroy()
assets/hooks/menu.ts
Store submenuWireTimer from nested menu wiring
Clear the timer in destroyed() before tearing down menus
Guard the wiring callback when this.menu is gone
Set this.menu = undefined after destroy

Tests

assets/test/component/menu.test.ts: subscription replacement and destroy cleanup
assets/test/hooks/menu.test.ts: destroyed hook cancels pending wiring timer
assets/test/helpers/mock-hook.ts: shared mockHookContext, callHookMounted, callHookDestroyed for hook lifecycle tests

Track and tear down submenu trigger subscriptions before re-wiring,
unsubscribe on menu destroy, and cancel pending submenu wiring timers
when the LiveView hook is destroyed.
@karim-semmoud karim-semmoud self-assigned this Jun 1, 2026
@karim-semmoud karim-semmoud changed the title Fix menu submenu machine.subscribe accumulation Fix(menu): submenu machine.subscribe accumulation Jun 1, 2026
@karim-semmoud karim-semmoud merged commit 028e2cd into main Jun 1, 2026
14 checks passed
@karim-semmoud karim-semmoud deleted the fix/menu-submenu-subscribe-leak branch June 1, 2026 08:41
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.

1 participant