Uh oh!
There was an error while loading. Please reload this page.
fix(site): the catalog gallery registers every plugin its entries need (#4616) - #4628
Merged
Merged
Conversation
#4616) The gallery page renders every catalog entry through a real SchemaRenderer, but ComponentRegistry only knows a type once the package owning it has loaded. #4600 registered the two packages its own category needed; measured on e028dfc, that left 33 of the 423 entries painting the red OBJUI-001 panel across 14 categories. registerCatalogBlocks now loads the nine further packages that census resolves to. Cost measured first, per the ruling: the docs route's first-load JS goes 7738.7 kB -> 9542.6 kB (+23.3%), against a +50% stop condition, with the prerender unaffected (556/556 static pages, all 440 thumbnail frames). A new category-wide render pin generalizes #4600's dashboard-only one to all 423 entries and three diagnostics, with every entry registration cannot reach named as an exclusion rather than skipped: #4624, #4625, #4626, #4627. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
The latest updates on your projects. Learn more about Vercel for GitHub. |
…ips Monaco Three follow-ups measured after the first commit: - examples/schema-catalog did not declare the nine plugin packages the new pin imports. Vitest resolved them through the workspace root, so the suite was green while `tsc -p tsconfig.test.json` failed with nine TS2882s — a gate the test run cannot see. Declared as devDependencies. - Rendering `code-editor` mounts Monaco, whose CDN loader script happy-dom cannot fetch; the resource-load error event made vitest exit 1 with all 2534 tests passing. The three plugin-editor entries are now named exclusions, the way packages/plugin-editor/src/index.test.ts already handles the same cost; `code-editor` being registered stays pinned in the control case. - Header corrections so the exclusion tables and the prose agree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Rendering the three plugin-map entries mounted maplibre for real. Two problems,
the second decisive:
- it refuses to initialise without WebGL2 ("WebGL2 is required to display this
map") and then trips SchemaRenderer's error boundary tearing its own painter
down, so the pin already had to lift every assertion but one for them;
- it fetches its style from https://demotiles.maplibre.org over the real
network. A unit test that reaches a third-party host is nondeterministic and
makes CI depend on that host being up, whatever it asserts.
All five of packages/plugin-map's own test files mock 'react-map-gl/maplibre'
for this reason. This pin renders the gallery's real stack so it cannot mock,
and abstains instead: the three entries join plugin-editor's in EXCLUSIONS, and
ComponentRegistry.get('object-map') in the control case is what stays pinned —
which is what #4616 changed for that bucket. Drops the UNKNOWN_PANEL_ONLY tier,
now empty.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 14, 2026 03:31
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
Fixes#4616
/docs/guide/schema-catalogrenders every catalog entry through a realSchemaRenderer, butComponentRegistryonly knows a type once the package owning it has loaded. #4600 (PR #4615) registered the two packages its own category needed. This registers the rest of the census, after measuring what that costs.1. Cost measurement (ruling 1) — the gate, run before deciding
The named instrument does not exist in this toolchain, so this substitutes the same quantity rather than inventing a table. Next 16.3 + Turbopack prints no
Size/First Load JScolumns innext build— its route output is the tree of route paths only. The figure below is reconstructed from the build on disk the way Next computes it: thescript srcset of the route's prerendered HTML, summed. All three counting tiers (script src,+ preload, every chunk referenced anywhere in the document) agree exactly, so the number is not sensitive to which refs you count.pnpm turbo run build --filter='@object-ui/site' --concurrency=2, before and after:/docs/guide/schema-catalogfirst-load JS/docs/guide/architecturefirst-load JS/playgroundfirst-load JSstatic/chunksVerdict: within budget. +23.3% against the ruling's ~50% stop condition, and the prerender does not break — so the eager default stands and the lazy
registerLazyfallback does not become a decision. Re-measured after the second commit; identical.Three measured facts the table makes visible, all worth knowing before reviewing the trade:
/docs/guide/architecturemoves identically to the gallery, because all 181 docs pages are one/docs/[[...slug]]route entry andSchemaThumbnail's own code sits in a chunk they all load. The cost is paid by every docs page, not just the gallery./playgroundis byte-identical, so the widening is confined to that route.PluginLoader; what changed is which chunks the docs route pulls in up front.SchemaThumbnailgates its mount behind anIntersectionObserver, so the OBJUI-001 panels appeared on the client after hydration, and both builds prerender 440 empty frames. The eagerness still matters — it is what makes registration precede a tile's first client render — but not for the reason the module header previously implied. Corrected there.2. Bucket census (ruling 2) — the true mapping, measured here
The issue's buckets were a root-type census against
@object-ui/components+registerLayout(). Re-measured by rendering all 423 entries the waySchemaThumbnailrenders them, against the registration set as it actually stood after #4615:Measured: 33 entries, 33 panels — not 35. The issue's 35 counted the pre-#4615 state for
dashboard/chart. The full root census reproduces the issue's 44 exactly; 12 of those (9dashboard, 2chart, 1bar-chart) were already fixed by #4615, and one entry (components-form-calendar/form-integration) is adivwhose nested node is unresolved, so it is absent from a root census and present in a rendered one.calendarchatbotcode-editorobject-ganttobject-mapmarkdowntimelinecalendar-viewkanbanfilter-uisort-uiview-switchersingleunknown-componentNine packages, appended to
registerCatalogBlocksafter #4600's two:plugin-calendar,plugin-chatbot,plugin-editor,plugin-gantt,plugin-kanban,plugin-map,plugin-markdown,plugin-timeline,plugin-view. All nine were already dependencies andtranspilePackagesentries ofapps/site, so neither itspackage.jsonnornext.config.mjschanged. Import order is preserved as contract and documented: several packages claim the same bare keyword (chart,calendar) and the last registration wins.Result: 31 of the 33 tiles go from the red panel to a drawn component.
3. Red-first, verbatim
Same harness, run against the two registration sets. Before (the set on
origin/main@e028dfcd8):After (this branch's set):
4. The generalized pin (ruling 3)
examples/schema-catalog/test/catalog-gallery-render.test.tsx— all 423 entries, every category, rendered exactly asSchemaThumbnailrenders them (same registration set in the same order,SidebarProvider,toRenderableSchema, the dataset stub as both context and prop).It asserts three diagnostics, not one. Naming only OBJUI-001 would have reported #4625's six entries as fixed: registering
plugin-calendartrades their red panel forObjectCalendar's inlineDataSource required for object/api providers. That string is asserted corpus-wide alongside the panel and theSchemaRenderererror boundary.Two deliberate departures from #4600's pin, both measured:
role=alertis not asserted category-wide.components-data-display-alert's two entries carry it because that is what an Alert is. Correct for a dashboard tile, wrong for the corpus.components-basic-text/*render a bare text node with no element around it, so an element-count-only control reads nine correct tiles as empty.That control earned its place immediately: it found two entries that render a completely blank tile — invisible to any red-tile sweep — now filed as #4626.
5. Named exclusions, with reasons (ruling 4)
Censused, not silently skipped; a dedicated case fails if an excluded id stops existing. Nothing here had its semantics rewritten.
Not rendered by the pin (7)
core-schema-renderer/unknown-component-typecomponents-disclosure-toggle-group/with-labelssingle; its two siblings spell ittoggle-group+selectionType: singlecomponents-overlay-tooltip/basic-tooltipchildren, which the renderer never readscomponents-overlay-hover-card/basic-hover-cardvaluewhere the text renderer readscontentplugin-editor/*(3)code-editormakes@monaco-editor/reactappend a CDN loaderscripthappy-dom cannot fetch. The resource-load error event makes vitest exit 1 with every assertion passing (measured: 2534/2534 green, 4 unhandled errors, exit 1).packages/plugin-editor/src/index.test.tssettled the same cost the same way — it asserts registration and never renders.ComponentRegistry.get('code-editor')stays pinned in the control case, which IS what this PR changed for that bucketOne named diagnostic exempted, every other assertion still applied (6) — the six
components-form-calendar/*, forDataSource required for object/api providers. They author the barecalendarkeyword, which@object-ui/componentsdeliberately registers asui:calendaronly (skipFallback: true, "collides with the plugin-calendar full CRUD calendar VIEW"), so it reachesObjectCalendar. Filed as #4625.OBJUI-001 half only (3) —
plugin-map/*. maplibre refuses to initialise without WebGL2 (GPUInitializationError: WebGL2 is required to display this map) and then trips the error boundary tearing its own painter down. A happy-dom property; what stays pinned is exactly what this PR fixed — the type resolves.Authored-title control lifted, everything else applied (2) — the two
plugin-calendar/*. Both draw a real calendar (163 and 421 elements);calendar-viewpaints the window around today and both author fixed 2024 dates, so no event title is in range. Filed as #4627.6. Reverse verification (directions predicted before running;
git checkout, nevergit stash)Two links, and they fail in different places on purpose — the pin registers its own packages and cannot import from
apps/**, so reverting the host does not and cannot red the sweep. That is precisely why the source-text parity case exists.(a) Host registrar reverted to
origin/main— predicted: the parity case alone, sweep untouched.(b) The pin's own nine imports removed — predicted: plain red across the sweep.
28 rather than 31 because the three
plugin-editorentries are not rendered at all — consistent with the exclusion above.7. Non-registration failures found and filed
All searched first (keyword + path); none had an open issue. All unassigned.
with-labelsnames root typesingle. The one unintentional OBJUI-001 tile left.components-form-calendar/*author the barecalendarkeyword.basic-tooltipandbasic-hover-cardrender blank tiles; each authors a key its own renderer never reads. Filed with the class question: nothing rejects an authored key a registered type does not declare, which is exactly how AI-authored metadata fails silently.finding) — the twoplugin-calendar/*entries' 2024 event dates. Nothing red, so nopm:queue.8. Verification
One lap's worth of that was earned rather than free, and is recorded because it is the kind of gap a test run cannot see:
examples/schema-catalogdid not declare the nine plugin packages the pin imports. Vitest resolved them through the workspace root and was green, whiletsc -p tsconfig.test.jsonfailed with nineTS2882s. Declared as devDependencies in the second commit — which is the only reasonpackage.jsonand the lockfile appear in this diff.9. Surface respected
InteractiveDemo/LiveSplitDemokeepPluginLoaderlazy loading — the fix(examples,docs): the dashboard gallery renders working charts again — filtered-* entries leave the retired shape (#4600) #4615 separation stands, and the pin now asserts neither importsregisterCatalogBlocks.page-header得红色错误面板);transpilePackages还列着两个非依赖包 #3904 guard stays green:registerCatalogBlocksstill does not re-exportregisterLayoutBlocks, and each host names the layout registrar directly.packages/components/src/renderers/complex/data-table.tsxandpackages/plugin-dashboardnode construction ([plugin-dashboard] atablewidget with inline static data crashes into the error boundary — "Maximum update depth exceeded" #4618's seat),content/docs/releases/**, metric-card spec validity (objectstack#8593), and every catalog entry's semantics — no entry JSON is modified by this PR.src/of a released package changed.check-changeset-presence.mjsconfirms it, andskip-changesetis applied, as on fix(examples,docs): the dashboard gallery renders working charts again — filtered-* entries leave the retired shape (#4600) #4615.Generated by Claude Code