docs(website): client extension slots, and the client half is one slice (phase 3, slice 2) #137

Merged
whitlocktech merged 2 commits from docs/module-client-slots into main 2026-08-11 21:54:09 +00:00

2 Commits

Author SHA1 Message Date
96b364b0bc docs(website): record slice 2, and what the browser changed about it
The contract as written had core branch on hasExtension to decide about its own
decoration around a slot. That is right when nothing is installed and wrong when
something is installed and fails: the slot IS filled, so the separator renders,
and the component then throws into the boundary and leaves the separator behind
on its own. Core decorates through <Slot wrap> now, inside the boundary, and
hasExtension is gone rather than kept as a trap for the next caller. Every unit
test passed both before and after -- the 7.7 browser smoke is what saw it.

Also recorded, neither a defect: core's own fill occupies a slot, so a module
cannot fill either one until the client half deletes core's (worth stating,
because a module written against 1.2.0 today cannot use them); and core's UO
sections on the user-detail page now fail to load, which is slice 1 removing the
routes rather than anything this slice did.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-11 16:46:11 -05:00
262c86ad4f docs(website): client extension slots, and the client half is one slice
Two findings from surveying the client half, and one org-lead decision that
turns them into the same piece of work.

The client half does not divide into public and admin after all. Routes slice by
area, but useShardFeed and shardEvents are imported by eight public pages AND
three admin views, and a shared leaf moves with its last consumer -- the same
rule the server half taught. Of the three ways out, two trade a real cost for a
boundary that lasts one review, so the client half is one slice. The nav rows
keep their feature provider as a consequence (rows without it fail open, so
disabled surfaces would advertise themselves again), and VendorSales turns out
to have no public consumer at all.

Its three consumers include core's own UserDetail, which renders six UO sections
with nowhere to put them: the server got declareSlot/registerExtension in phase
2 PR 4 and the client never got the twin. SiteFooter's link to a URL the
extraction deletes is the same gap one component over.

So slice 2 is core-only and adds rather than moves: client extension slots
(API 3.7), the site.footer.status and admin.users.detail slots, core filling
both itself. MODULE_API_VERSION goes to 1.2.0.

A slot is named for a PLACE, never for a meaning -- core supplies the position
and the styling, the module owns the label, the target, the data and whether it
renders at all. Typing a slot by its content would put game semantics back into
core, which is what this phase removes.

This is also the one slice where core merges before module-uo, because a chunk
cannot call registerExtension before the function exists. Harmless here: the
slice only adds, and core fills both slots with its own components under owner
id `core`, so the page is unchanged and the mechanism is proved before anything
moves.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-11 16:32:08 -05:00