@@ -2,15 +2,21 @@ import "dart:async";
22
33import "package:duit_kernel/duit_kernel.dart" ;
44import "package:duit_kernel/src/registry_api/components/index.dart" ;
5+ import "package:meta/meta.dart" ;
6+
7+ const _messageExternalLibrarySupportNotEnabled =
8+ "External library support is not enabled" ;
59
610/// The [DuitRegistry] class is responsible for registering and retrieving
711/// model factories, build factories, and attributes factories for custom DUIT elements.
812sealed class DuitRegistry {
913 static final Map <String , BuildFactory > _customComponentRegistry = {};
1014 static final Map <String , Map <String , dynamic >> _fragmentRegistry = {};
11- static LoggingCapabilityDelegate _logManager = const LoggingManager ();
1215 static ComponentRegistry _componentRegistry = DefaultComponentRegistry ();
1316 static DuitTheme _theme = const DuitTheme ({});
17+ static LoggingCapabilityDelegate _logManager = const LoggingManager ();
18+ static late final Map <String , LibraryDescriptor > _libraries;
19+ static late final Map <String , LibraryDescriptor > _reverseIndex;
1420
1521 static FutureOr <void > initialize ({
1622 @Deprecated ("Will be removed in the next major release." )
@@ -23,6 +29,11 @@ sealed class DuitRegistry {
2329 _theme = theme ?? _theme;
2430 _logManager = logManager ?? _logManager;
2531 await _componentRegistry.init ();
32+
33+ if (enableExternalLibrarySupport) {
34+ _libraries = {};
35+ _reverseIndex = {};
36+ }
2637 }
2738
2839 static DuitTheme get theme => _theme;
@@ -155,4 +166,68 @@ sealed class DuitRegistry {
155166 DuitDataSource .registerCustomObjectFactory (toClass);
156167 _logManager.logInfo ("Custom object factory for $T registered successfully" );
157168 }
169+
170+ /// Loads an external [LibraryDescriptor] into the registry.
171+ ///
172+ /// The [library] argument must be a compile-time constant (`@mustBeConst` ).
173+ /// After loading, every [WidgetDescriptor] declared in
174+ /// [LibraryDescriptor.descriptors] is indexed in the internal reverse-lookup
175+ /// map so that [getDescriptor] and [hasDescriptor] can resolve widget types
176+ /// at O(1) cost.
177+ ///
178+ /// Loading the same library name twice is a no-op (an error is logged and
179+ /// the call returns immediately). Similarly, if a widget type key from the
180+ /// new library already exists in the reverse index (registered by a
181+ /// previously loaded library), an error is logged and that descriptor is
182+ /// skipped.
183+ ///
184+ /// Example:
185+ /// ```dart
186+ /// DuitRegistry.loadLibrary(const MyWidgetLibrary());
187+ /// ```
188+ @experimental
189+ static void loadLibrary (@mustBeConst LibraryDescriptor library) {
190+ if (enableExternalLibrarySupport) {
191+ if (_libraries.containsKey (library.name)) {
192+ _logManager.logError ("Library ${library .name } already loaded" );
193+ return ;
194+ }
195+ _libraries[library.name] = library;
196+ for (final key in library.descriptors.keys) {
197+ _reverseIndex[key] = library;
198+ }
199+ } else {
200+ _logManager.logCritical (_messageExternalLibrarySupportNotEnabled);
201+ throw UnsupportedError (_messageExternalLibrarySupportNotEnabled);
202+ }
203+ }
204+
205+ /// Returns the [WidgetDescriptor] for [name] from the loaded external
206+ /// libraries, or `null` if no descriptor with that widget type has been
207+ /// registered.
208+ ///
209+ /// Uses the internal reverse-index built by [loadLibrary] for O(1) lookup.
210+ @experimental
211+ @preferInline
212+ static WidgetDescriptor ? getDescriptor (String name) {
213+ if (enableExternalLibrarySupport) {
214+ return _reverseIndex[name]? .getDescriptor (name);
215+ } else {
216+ _logManager.logCritical (_messageExternalLibrarySupportNotEnabled);
217+ throw UnsupportedError (_messageExternalLibrarySupportNotEnabled);
218+ }
219+ }
220+
221+ /// Returns `true` if an external library loaded via [loadLibrary] contains a
222+ /// [WidgetDescriptor] whose type equals [name] .
223+ @experimental
224+ @preferInline
225+ static bool hasDescriptor (String name) {
226+ if (enableExternalLibrarySupport) {
227+ return _reverseIndex[name]? .hasDescriptor (name) ?? false ;
228+ } else {
229+ _logManager.logCritical (_messageExternalLibrarySupportNotEnabled);
230+ throw UnsupportedError (_messageExternalLibrarySupportNotEnabled);
231+ }
232+ }
158233}
0 commit comments