3.1 KiB
<PackRegistryProvider> — chassis pack registry
(no submodules)
Purpose
Mounts the active pack registry, validates every pack against
ComponentPackSchema plus the no-collision invariant, runs each pack's
onRegister(ctx) hook in declared order on mount, runs
onUnregister(ctx) in reverse order on unmount, forwards each pack's
translation bundles into the active i18n catalog under the pack's name
as the namespace, and emits the OTel signals defined in the proposal.
Features
- Validates packs synchronously at mount; throws
ReactUiError(REACT_UI.PACK_NAME_COLLISION)when two packs share aname - Registration in declared order; teardown in reverse order
- Each pack receives a
PackContextcontaining the active i18n instance, active theme, aPackLoggerLike(defaulting to a console-backed shim), and anAbortSignalscoped to the pack's mount lifetime - Pack translations auto-registered via
i18n.catalog.set(locale, packName, bundle)so consumers readingt('packName:key')see the registered values peerRangemismatch logs a structured warning AND incrementsreact_ui.pack.version_mismatch_total— the pack still registers (degrades gracefully, never throws)- Runtime override map (
<ReactUiProvider components={...}>) merges on top of pack defaults at registration time - OTel: counters
react_ui.pack.register_total,react_ui.pack.unregister_total,react_ui.pack.version_mismatch_total; spanreact_ui.pack.register{name}around eachonRegister
Usage: Basic example
import { PackRegistryProvider } from "@suaveplan/react-ui/pack/pack-registry-provider";
<PackRegistryProvider i18n={i18n} packs={[authPack]}>
<App />
</PackRegistryProvider>;
Usage: Advanced example
import { PackRegistryProvider } from "@suaveplan/react-ui/pack/pack-registry-provider";
<PackRegistryProvider
i18n={i18n}
packs={[authPack, socialPack, billingPack]}
components={{
auth: { LoginForm: AcmeLoginForm },
social: { ShareButton: AcmeShareButton },
}}
logger={{ warn: log.warn, info: log.info }}
>
<App />
</PackRegistryProvider>;
API Reference
<PackRegistryProvider>— props perPackRegistryProviderProps:i18n: I18nInstance— required; pack translations register herepacks: ReadonlyArray<ComponentPack>— requiredcomponents?: RuntimeComponentOverride— optional override maplogger?: PackLoggerLike— optional; defaults to a console-backed shimchildren: ReactNode
Implementation notes
The provider enforces TWO validation passes at mount time: the
collision check (synchronous, throws on duplicate name) and the schema
check (synchronous, throws on bad shape). Both run BEFORE any
onRegister hook fires so a partially-registered registry never
exists. onRegister runs inside an OTel span so failures inside a
pack's hook are attributable to the pack name in trace storage. The
teardown loop iterates in reverse so packs that depend on earlier
packs (e.g. a billing pack assuming auth is mounted) tear down in
the safe order.