Skip to content

feat(routes): let a consumer unregister a single route - #13

Merged
Upd4ting merged 2 commits into
mainfrom
feat/unregister-route
Aug 10, 2026
Merged

feat(routes): let a consumer unregister a single route#13
Upd4ting merged 2 commits into
mainfrom
feat/unregister-route

Conversation

@Upd4ting

@Upd4ting Upd4ting commented Aug 9, 2026

Copy link
Copy Markdown
Member

Routes are only released when their module unloads. Anything with a shorter life than its module therefore keeps answering after the thing that registered it is gone — the case that prompted this is a CMS page unregistered while its module stays loaded: its /pagelayout route kept serving.

routesProxy is exported and RoutesProxy.unregister already does the right cleanup (it prunes routesList as well), but a consumer cannot use it: interface resolution rebinds the export, so the object the consumer imports is not the one holding the live registry. Verified in the AntelopeJS test harness — internal.routesProxy !== routesProxy, and neither removes a route from getRegisteredRoutes().

Hence a real API next to RegisterRoute, taking the id it returns.

const id = RegisterRoute({ ... });
// later, when whatever owns the route goes away
UnregisterRoute(id);

Consumer waiting on this: AntelopeJS/cms#301, where a page now owns and releases everything it registered — every registry but this one.

Greptile Summary

The PR adds a public API for unregistering an individual route using the ID returned during registration.

  • Adds UnregisterRoute, which delegates cleanup to the live route proxy.
  • Adds lifecycle regression tests covering targeted removal, preservation of unrelated routes, repeated removal, and unknown IDs.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/index.ts Adds the public single-route cleanup API using the existing proxy lifecycle behavior.
src/tests/route-lifecycle.test.ts Adds focused regression coverage that resolves the prior concern about route cleanup behavior.

Reviews (3): Last reviewed commit: "test(routes): cover the route lifecycle" | Re-trigger Greptile

Routes are only released when their module unloads, so anything with a
shorter life than its module keeps answering after the thing that
registered it is gone — a CMS page unregistered while its module stays
loaded still serves its own layout route.

The proxy that could do it is exported, but interface resolution rebinds
it, so the object a consumer imports is not the one holding the live
registry: the handle has to come from here.
Comment thread src/index.ts
@Upd4ting

Copy link
Copy Markdown
Member Author

@greptile review

Three cases on the new UnregisterRoute: the id RegisterRoute returned
releases exactly that route from the public listing while a bystander
keeps serving, with the proxy hearing the string-keyed id; the same id
tolerated twice; an id never registered ignored.

The cases run against the local build, whose proxy no module attaches in
the test harness — the api module binds the harness-distributed copy of
the interface. A recording provider keeps the stub-mode proxy from
throwing and lets the assertions see what reaches the real registry.
@Upd4ting

Copy link
Copy Markdown
Member Author

@greptile review

@Upd4ting
Upd4ting merged commit 8e606d0 into main Aug 10, 2026
3 checks passed
@Upd4ting
Upd4ting deleted the feat/unregister-route branch August 10, 2026 14:29
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