Docs
/
a domain door, once

@leumas/domain-kit

A DOMAIN DOOR, once — the overview HUD, its view host, the console nav view and the manifest→routes/aside/crumbs/⌘K derivation every product's admin repeats. The 3D room is a separate, optional...

@leumas/domain-kit — a domain door, once

Leumas Studio and Leumas Admin are different products for different people, and they draw a domain the same way on purpose: a door you land on, a deck of what is inside it, view modes over that same list, a tab strip under each page, one aside, one breadcrumb trail, one ⌘K. An operator moves between the two consoles all day, so "the same" has to mean the same code, not the same screenshot.

This package is that code. It was Studio-local until every one of its behaviours had to exist in the control plane too.

Subpaths

ImportWhat you getTouches three?
@leumas/domain-kitDomainOverviewHud, useSeededFocus, DomainViewHost, DOMAIN_VIEWS, useArrowStep, registerDomainRoom, getDomainRoom, HudDeckFigure, useSettledFocus, useDomainScope, scopeHref/unscopeHref/scopeFromPathno
@leumas/domain-kit/routesDomainRoutes, DomainLanding, DomainHub, domainsToRoutes, blockingFeature, CrumbTitleContext, useCrumbTitleno
@leumas/domain-kit/console-viewside effect: registers the console nav viewno
@leumas/domain-kit/roomside effect: registers the 3D roomyes
@leumas/domain-kit/room/backdropDomainWorldBackdrop for a surface drawing its own stageyes
@leumas/domain-kit/domain-hud.css.lms-dhud__* (the shell imports it itself)no

The room is opt-in, and that is a bundle decision

DomainOverviewHud does not import the backdrop. It asks roomRegistry.js for a component, and a product opts in with one line in its entry:

import '@leumas/domain-kit/console-view';
import '@leumas/domain-kit/room';        // ← without this line, no renderer in the build

lazy(() => import('./DomainWorldBackdrop.jsx')) inside the shell would look free — it is behind a promise — but it is an unconditional module edge, so every consumer emits a three chunk whether or not any door passes a load. Runtime already degrades correctly, so the defect is invisible in a browser and only ever shows up as a renderer in someone's dist/. A product without the room import gets identical doors minus the backdrop: they render their fallbackStage.

pnpm check:huds asserts the shell mentions neither three nor @leumas/cinematic, and that no domain console imports /room directly.

A character-select deck: HudDeckFigure + useSettledFocus

Two doors draw a deck where the item IS the picture (chrome="none") — AI's personas and Hosting's websites — and they arrived at the same box independently. HudDeckFigure is that box: a poster that is always there and always cheap, an optional live layer over it, a plate, and pills that render only on the centred item.

The poster is never unmounted, only faded. That is the entire failure story: it costs one composited element, the card never reflows when the expensive layer swaps in, and there is no code path to write for a snapshot that never rendered, a document that refused to frame, or a dead WebGL context — because the failure state is the resting state.

useSettledFocus(focusId, ms) reports the focus id only once the deck has stopped moving. Both decks need it for the same reason: a held arrow key steps several cards a second, and mounting the expensive layer per step churns WebGL contexts (browsers cap them near sixteen and drop the oldest, so a long deck starts killing the room drawn behind it — with the symptom appearing nowhere near the cause).

[warning] Not useSeededFocus, which picks the initial focus. Adjacent name, unrelated job.

Five layout rules live in domainhud.css beside the code they constrain, each one a defect that already shipped: the media is position: absolute; inset: 0 and never block-size: 100%; one z-index puts both layers over a door's decorative pseudo-elements; transitions are transform and opacity only; no backdrop-filter anywhere on a deck over a live canvas; a filter may sit on a still element and never on a moving one.

A scoped domain: the thing is in the URL

Some domains are about one of the operator's things — Hosting is about one website, and every one of its tabs is. That subject belongs in the address, not in a component's state:

/admin/hosting/sites/<siteId>/domains

The nav manifest declares those tabs unscoped (/admin/hosting/sites/domains) and marks the sub-item scoped: true. It has to: four guard scripts and the diagram generator read the manifest in bare Node, where there is no current site and never can be. So the manifest states the shape and DomainRoutes reads the id out of the location, publishing it on DomainScopeContext.

Compare unscoped, emit scoped. sectionRows decides which row is active by matching its hrefs against the location, so it is given the location with the id removed; the rows it returns get the id put back. Reversing that is silent — nothing matches, no row is active, and the aside looks like it lost its place rather than like it has a bug. scopePath.js is plain JS so a bare-Node test can pin both directions (test/domain-scope.test.js).

With no scoped sub-item in a domain, useDomainScope() returns null and every consumer behaves exactly as it did before scopes existed — which is what keeps the other doors byte-identical.

The two rules the shell will not break

  • It never fetches. Every domain keeps its own data source and hands down items, status,

loading, onRetry.

  • It never gates. useCanvasCapable() belongs in the caller's default export — except under

downgrade: 'stage', where the registered room asks it and swaps only the stage.

One AdminSurface, ever. It is rendered by DomainOverviewHud, so a caller must not wrap it in another.

Adding a domain to a product

  1. <domain>/model/tabs.js — THE tab list, pure data, no JSX (guards import it in bare Node).
  2. <domain>/hud/overview.js — the spec: `{ id, base, hudLabel, deckLabel, surface, select, footer,

downgrade, room? }. id` must equal the folder name.

  1. <domain>/hud/<Domain>Populators.js(api) => Promise<inhabitant[]>, **contracted never to

reject**. Only if the door draws a room.

  1. <domain>/hud/<Domain>Hud.jsx — the door: DomainViewHost whose renderConsole is a

DomainOverviewHud spread from the spec.

  1. <domain>/pages/<Domain>Hub.jsx — the tabbed surface: RouteTabs + a nested <Routes> of lazy

panels. activeTabId() is the only source of "which tab is open".

  1. One manifest sub-item carrying tabs, and one LANDINGS entry for the door.

node ops/tools/domain-scaffold/index.mjs --product admin --domain <id> writes 1, 2, 4 and 5 from the manifest.

What it exports

66 exports: 28 components, 11 hooks, 27 helpers. Import from @leumas/domain-kit.

ACT_VERBSActiveDomainContextActiveDomainContextCrumbTitleContextDOMAIN_VIEWSDomainDoorDomainHubDomainLandingDomainOverviewHudDomainRailDomainRoomDomainRoutesDomainScopeContextDomainScopeProviderDomainViewHostDomainWorldBackdropDRILL_PARAMGenericDomainOverviewHudDeckBadgeHudDeckFigureMAX_ACTSPILLAR_FALLBACKPILLAR_ROOMRedirectSubtreeSETTLE_MSSTAGE_MAXToneScopeXuseActiveDomainuseActiveDomainuseArrowStepuseCrumbTitleuseDomainCountsuseDomainEntitiesuseDomainScopeuseDomainSectionsuseDrilluseSeededFocususeSettledFocusactsForblockingFeatureclearDomainCountsclearDomainEntitiescountsByKinddeckItemsFordomainsToRoutesgetDomainRoomindexIteminhabitantsFromEntitiesinhabitantsFromTabsisOnlookForoverviewForpeekDomainEntitiespillarRoomprimaryActForreadDomainEntitiesreadScopeSearchregisterDomainRoomscopeFromPathscopeHrefscopeSearchstripBasetoneForturnForunscopeHref
Source shared/packages/domain-kit/README.md (no-git)markdownjson
Generated from the Leumas repository. Every page cites the file it came from.leumas.techllms.txt