Found while implementing #5476 (PR #5599). Filed unassigned, not fixed there — out of that card's scope, and it is an observation about layering rather than a user-reachable defect.
What is there
packages/app-shell/src/views/metadata-admin/nav-selection.ts is otherwise pure string plumbing — parseSurfaceParam / formatSurfaceParam / parseNavSelParam and friends, the URL-boundary translation the designer's deep-links use. Its only import is:
// nav-selection.ts:14import{APP_NAV_ROOT_KEYS}from'./inspectors/AppNavInspector.js';and on the other end:
// AppNavInspector.tsx:510 — the last line of a 510-line React component moduleexportconstAPP_NAV_ROOT_KEYS=ROOT_KEYS;
So a module whose job is parsing a query-string statically pulls in a full inspector component — Radix, dnd-kit, icons and all — for one array of root keys.
Why it is worth recording
The pull is real and it reaches small consumers. Non-test importers of nav-selection today:
views/studio-design/useSurfaceDeepLink.ts
views/studio-design/StudioDesignSurface.tsx
views/metadata-admin/ResourceEditPage.tsx
utils/appRoute.ts
console/ai/artifactStudioPath.ts
The last two are small utilities that want a URL helper and nothing else.
It also already shapes code around itself. #5476 needed the pending-changes sheet — which sits in the console's EAGER graph — to consume a small piece of surface plumbing, and the fix had to be put in a separate React-only module specifically so that importing it would not reach nav-selection, and through it the inspector. That is a workaround for this edge, written down in a comment in surfaceDeepLinkChannel.ts. It is the second bundle-defensive note in that neighbourhood; DraftChangesPanel.tsx already carries a measured one about @objectstack/spec.
Shape of a fix (not a decision, just the obvious one)
Move ROOT_KEYS to a leaf module both sides import — or into nav-selection.ts itself, with AppNavInspector importing it from there, since the constant describes the nav SHAPE rather than the editor. Either direction ends the edge; the second inverts it the way the dependency actually runs.
Worth measuring against check-eager-closure-budget before and after: the console's eager closure is currently 3785.3 KB gzipped against a 3867.2 KB budget, i.e. 81.9 KB of headroom, so this is a candidate for buying some back rather than only a tidiness argument.
Found while implementing #5476 (PR #5599). Filed unassigned, not fixed there — out of that card's scope, and it is an observation about layering rather than a user-reachable defect.
What is there
packages/app-shell/src/views/metadata-admin/nav-selection.tsis otherwise pure string plumbing —parseSurfaceParam/formatSurfaceParam/parseNavSelParamand friends, the URL-boundary translation the designer's deep-links use. Its only import is:and on the other end:
So a module whose job is parsing a query-string statically pulls in a full inspector component — Radix, dnd-kit, icons and all — for one array of root keys.
Why it is worth recording
The pull is real and it reaches small consumers. Non-test importers of
nav-selectiontoday:The last two are small utilities that want a URL helper and nothing else.
It also already shapes code around itself. #5476 needed the pending-changes sheet — which sits in the console's EAGER graph — to consume a small piece of surface plumbing, and the fix had to be put in a separate React-only module specifically so that importing it would not reach
nav-selection, and through it the inspector. That is a workaround for this edge, written down in a comment insurfaceDeepLinkChannel.ts. It is the second bundle-defensive note in that neighbourhood;DraftChangesPanel.tsxalready carries a measured one about@objectstack/spec.Shape of a fix (not a decision, just the obvious one)
Move
ROOT_KEYSto a leaf module both sides import — or intonav-selection.tsitself, withAppNavInspectorimporting it from there, since the constant describes the nav SHAPE rather than the editor. Either direction ends the edge; the second inverts it the way the dependency actually runs.Worth measuring against
check-eager-closure-budgetbefore and after: the console's eager closure is currently 3785.3 KB gzipped against a 3867.2 KB budget, i.e. 81.9 KB of headroom, so this is a candidate for buying some back rather than only a tidiness argument.