fix: fire on-enter for the default route at startup (#81) - #87
Merged
Conversation
A `<route>`'s `on-enter` hook did not fire for the default route when a `<router>` first mounted; it only fired on subsequent navigations. The initial path is seeded through lazy initialization (`router_current_path`, from the render pass) without a path *change*, so `apply_one_navigation` — which fires hooks only when `old_path != new_path` — never saw the initial mount and skipped its `on-enter`. Mirror the existing deferred-navigation design: when `router_current_path` first seeds a router to its `default` (or `--route` override), enqueue the router id in a new `pending_initial_enters` queue and ping `data_notify`. The App poll loop drains it via `fire_pending_initial_enters()` right after `apply_pending_navigations()` and before the data-update pass, projecting the route and firing its `on-enter` once, outside the extension lock (the same re-entrancy-safe apply point as navigation hooks). Firing is deferred out of the render pass because `call_handler` holds the extension write lock. Adds regression test `test_initial_default_route_fires_on_enter`; updates the routing KB doc and log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #87 +/- ##
=======================================
Coverage 56.59% 56.59%
=======================================
Files 78 78
Lines 6866 6866
=======================================
Hits 3886 3886
Misses 2980 2980 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Summary
Fixes #81. A
<route>'son-enterhook did not fire for the default route when a<router>first mounted at startup — it only fired on subsequent navigations, makingon-enterunusable for "run something when the initial page is shown."Root cause: the initial path is seeded through lazy initialization (
router_current_path, called from the render pass) without a path change, soapply_one_navigation— which fireson-leave/on-enteronly whenold_path != new_path— never sees the initial mount and skips itson-enter.Approach
Firing from the render pass directly would risk a re-entrant deadlock (
call_handlerholds theextension_managerwrite lock), so this mirrors the existing deferred-navigation design:pending_initial_entersqueue onNemoRuntime.router_current_pathfirst seeds a router to itsdefault(or--routeoverride), it enqueues the router id and pingsdata_notify(once — later renders find existing state).fire_pending_initial_enters()drains the queue, projects the route's path+params, and fires itson-enteronce, outside the extension lock.Apppoll loop calls it right afterapply_pending_navigations()and before the data-update pass, so the projection propagates in the same wake.Result: the default route's
on-enterfires at startup, consistent with later navigations; each route'son-enterfires exactly once when it becomes active.Testing
test_initial_default_route_fires_on_enter(fires with no prior navigation; fires exactly once).--routeoverride tests still pass; clippy clean.Docs
Updated
docs/knowledgebase/patterns/routing.mdand added alog.mdentry.🤖 Generated with Claude Code