ReadonlyidUnique module identifier within the GeoLeaf instance.
Same uniqueness rule as ILifecycleModule.id — the registry is
idempotent, so re-registering the same id is a silent no-op.
Optional ReadonlydependenciesDeclared dependencies, if any.
Optional here (unlike ILifecycleModule) because a UI-only slot has
no init() to order. The registry reads it as dependencies ?? []
(app/module-registry.ts:210,231,288).
ReadonlyuiUI slot declaration — required: it is the whole point of this shape.
OptionalinitNever present. A slot carrying init is a ILifecycleModule.
OptionaldestroyNever present. A slot carrying destroy is a ILifecycleModule.
A registration that contributes only a UI slot — no boot lifecycle.
This is the shape a lazy plugin uses to place a toolbar pill or a desktop tab without embarking any code at boot: the registry stores it for UI queries and never calls lifecycle hooks on it.
⚠ This shape is not a recent addition — it is what
ModuleRegistry.register()has always accepted (app/module-registry.ts:58-81validates exactly these two shapes) and what every plugin already passes. It was simply absent from the contract, which declareddependencies,initanddestroyas required. The omission was invisible while the contract stayed private; publishing it (API publique S3) is what forced the correction, since the 8 real call sites —addpoi/src/entry.ts:163,185,editor:446,geocoding:77,measure:57,print:55,storage/…/toolbar-registration.ts:52and_plugin-template:50— would all have been rejected by the type they are supposed to satisfy.Example