fix(mapbox): autoload map children declared with the hidden attribute - #655
titouanmathis wants to merge 1 commit into
Conversation
Map children configure the map from markup that renders nothing, and the package documents `hidden` on those elements. The whole `@studiometa/ui-mapbox` catalog declared `visible`, which installs an `IntersectionObserver` on the element: a `hidden` element is never rendered, never intersects, and its dynamic `import()` never ran. A catalog component can now declare its own strategy, and the twelve map children declare `eager`. The registry only schedules a token an element declares, so the import happens because the element exists and runs on a background scheduler task. `MapboxMap` and `StoreLocator` render and keep `visible`, so the heavy `mapbox-gl` import stays gated behind the map. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LMSCm41fm3g7chxD728vAu
b30e482 to
93c5185
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 2.x #655 +/- ##
=========================================
Coverage 86.32% 86.32%
Complexity 145 145
=========================================
Files 20 20
Lines 746 746
Branches 88 88
=========================================
Hits 644 644
Misses 95 95
Partials 7 7
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Code ReviewRisk: Low — The manifest strategy override is scoped to the declarative Mapbox children while rendered roots remain viewport-gated; no blocking issues were found. This change adds per-component mount strategies to the manifest generator and regenerates the Mapbox manifest with Review usage: 63,395 in (39,563 cached) / 830 out tokens — $0.0194 (openrouter/openai/gpt-5.6-luna, thinking: low) Reviewed by @weareikko/code-review v0.9.5 for commit 93c5185. |
Map children declared with the
hiddenattribute never autoloaded.packages/ui-mapbox/src/catalog.tsdeclared onestrategy: 'visible'for the whole package, and the generator stamped it onto all 14 manifest entries. Thevisiblestrategy installs anIntersectionObserveron the element. Ahiddenelement is never rendered, so it never intersects, the dynamicimport()never runs, and nothing is logged.hiddenis the patternpackages/ui-mapbox/README.mdrecommends for the declarative-only children, so the two recommendations contradicted each other.What changed
scripts/manifest-types.ts—CuratedComponentMetadatatakes an optionalstrategy.scripts/generate-manifests.ts—serializeComponentserializescomponent.strategy ?? catalog.strategy.packages/ui-mapbox/src/catalog.ts— the package default staysvisible; the twelve map children declareeager.MapboxMapandStoreLocatorare the rendered roots and keepvisible.packages/ui-mapbox/src/manifest.ts— regenerated.Why
eageris right hereIn js-toolkit v4,
eagerdoes not mean "load at page load".The registry never walks the manifest.
reconcileElementreads thedata-componenttokens declared on an element and callsschedule(el, name)per token, so a manifest entry is consulted only for a name present in the DOM. Nothing loads for a token absent from the page.applyMountStrategyhandleseagerwithdefaultScheduler.background(mount), which posts throughscheduler.postTaskat background priority: deferred and off-frame. For a manifest source themounthook isimportPair, which callsentry.load(). Imports are deduplicated per name and the entry is deleted once loaded, so many markers on a page cost one import.So
eagermeans "no condition left to wait for beyond the element existing". That is what these declarative-only children need.idlewould also fix the bug but can delay controls and markers noticeably after the map appears. The heavymapbox-glimport stays gated behindMapboxMap, which keepsvisible.Tests
packages/tests/autoload/manifest.spec.tsasserted one uniform strategy per package. It now takes a per-token expectation, and a dedicated case lists both halves of the ui-mapbox split, so a new component fails the suite until it is classified.packages/tests/autoload/hidden-elements.spec.tsis new. It mounts aMapboxMapholdinghiddenchildren declared through the real package manifest and asserts each one loads and mounts, and it shows the contrast: avisibleentry on ahiddenelement is never imported. Both positive tests fail against the old uniformvisiblemanifest.Full suite: 87 files, 973 tests, all passing.
npm run manifest:checkandnpm run lintpass.Docs
packages/docs/guide/autoloading/index.mdgains a "Whateagermeans" section and a "Package defaults" section describing the ui-mapbox split, and the Mapbox integration note is corrected.packages/ui-mapbox/README.mdexplains why thehiddenchildren areeager(and its Usage section no longer shows theimportWhen*helpers, which js-toolkit v4 removed). The hand-written manifest examples in theMapboxMapreference and the vue-mapbox-gl migration guide gavevisibletoMapboxMarkerandMapboxPopup, which reproduces this bug; they now giveeager.Closes #625
🤖 Generated with Claude Code
https://claude.ai/code/session_01LMSCm41fm3g7chxD728vAu