description: "Slot registry pure core for the dsh web client: ordinary extension slots, reusable Component Factories, derived props types, store seats, and the renderer install contract."
English | 中文
dsh-client-ui-slots lets web client plugins define and compose typed UI regions. Ordinary Slots provide parent-owned extension positions; Component Factories provide reusable assemblies with caller-selected local Components. Both APIs derive scoped state, injection, locale, and child-render props from declaration-merged types and report conflicting definitions during plugin loading. Pair this React-free package with ui-renderer when the client needs rendering.
Compose UI through this package whenever you write a client plugin: register a component into a slot your parent declared, or declare child slots your component renders. The four kinds cover the composition shapes — single (one occupant), list (ordered entries), keyed (dispatch by a key), and chain (entries elect themselves).
Use a Component Factory when one package defines an assembly that unrelated parents render independently. Declare its complete type in SlotFactoryMap, install the definition with ctx.slots.registerFactory(), render occurrences through the injected renderFactorySlot(), and select each declared local Component through the call's slots option. The definition reads that choice through useFactorySlot(name, fallback).
Factory children remain ordinary global Slots and must match SlotMap, while local slots select one Component per occurrence. An occurrence inherits its render-position scope; renderFactorySlot() does not accept a Session identity. Shared Store handles use ordinary scope resolution. A Store factory stays lazy until an occurrence first materializes, then creates one handle for that render position and rejects a persistent Store spec whose key would collide across occurrences.
Every registered component receives props composed from five framework shares: the runtime share (owner from the parent's render call site, plus the session standard kit and global seat), the child-render share (renderSlot statically narrowed to declared children), the Factory-render share (renderFactorySlot), the store share (the declared handle's selector hook and draft-stripped actions), and the business share (inferred from inject). Components reference the derived props aliases; they never re-type a share locally.
A register call may declare a store seat with store: defineStore(...): init infers the state schema and actions is the complete draft-transform write set. Components read through the selector hook and write through the baked callbacks; the engine implementation of defineStore lives in the runtime package and satisfies the DefineStore contract exported here.
Declaring a slot is claiming it: the registering entry becomes the only entry allowed to render that key, and registering into an undeclared slot, declaring an already-declared child, mounting one shared handle under two scopes, or registering a chain without select throws at load. An entry's disposer collapses its declared child slots recursively — ledger rows, contributions, and store mounts die on one lifecycle axis.
These pages cover the engine, the renderer, and the composition model.
None, as the package is a browser-side UI plugin layer that registers nothing model-facing.
None; this package neither assembles nor sends a provider request.
These limits define the registry's scaling behavior and accepted type noise; they are current package constraints.
isLive scans all records linearly — fine at UI-plugin registration counts (tens); revisit with an entry→record backref if ledgers ever grow hot.__renders phantom anchor is visible on PropsRenderSlots — the same accepted noise as the type-chain design's __accepts: generic method signatures compare loosely across key unions, so the contravariant marker is what enforces "component key set ⊆ children declaration".Runtime invariant: No companion is published. This is a zero-dependency pure registry core; it emits no Cordis events itself (the ui-renderer SlotRegistry owns the event bridge and its invariants); define/register/dispose sequencing is asserted directly by this package's behavior specs.