• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Duit-Foundation / flutter_duit / 21026233449

15 Jan 2026 09:26AM UTC coverage: 80.184% (-8.3%) from 88.441%
21026233449

push

github

web-flow
feat: Capability-based API migration pt2 (#323)

162 of 408 new or added lines in 23 files covered. (39.71%)

328 existing lines in 17 files now uncovered.

4354 of 5430 relevant lines covered (80.18%)

34.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.87
/lib/src/duit_impl/public_api_view.dart
1
import "package:duit_kernel/duit_kernel.dart";
2
import "package:flutter_duit/src/capabilities/index.dart";
3
import "package:flutter_duit/src/duit_impl/driver_compat.dart";
4
import "package:meta/meta.dart";
5

6
/// Public API for working with the Duit driver.
7
///
8
/// [XDriver] is an extension type wrapper over [UIDriver] that provides
9
/// a convenient interface for initializing and managing a Duit application
10
/// in various operating modes.
11
///
12
/// Supported modes:
13
/// - **Remote**: connection to a remote server through a transport layer
14
/// - **Static**: working with predefined JSON content without server requests
15
/// - **Native Module**: integration Duit as a module into an existing native application
16
///
17
/// The extension implements [FocusCapabilityDelegate] to support
18
/// UI focus management.
19
///
20
/// Usage example:
21
/// ```dart
22
/// // Creating a remote driver
23
/// final driver = XDriver.remote(
24
///   transportManager: MyTransportManager(),
25
///   initialRequestPayload: {'key': 'value'},
26
/// );
27
/// ```
28
extension type XDriver._(UIDriver _driver) implements FocusCapabilityDelegate {
29
  /// Creates a driver for working with a remote Duit server.
30
  ///
31
  /// This constructor is used when the UI should be dynamically loaded
32
  /// from the server through an established transport protocol.
33
  ///
34
  /// **Required parameters:**
35
  /// - [transportManager] - transport layer manager for server communication.
36
  ///   Responsible for sending requests and receiving UI updates.
37
  ///
38
  /// **Optional parameters:**
39
  /// - [initialRequestPayload] - additional data for the first server request.
40
  ///   May contain initialization parameters, authorization tokens, etc.
41
  /// - [nativeModuleManager] - delegate for managing native modules.
42
  ///   Allows calling platform-specific code.
43
  /// - [scriptingManager] - delegate for executing client-side scripts.
44
  ///   Extends application logic without modifying the UI.
45
  /// - [loggingManager] - delegate for customizing logging.
46
  ///   Allows intercepting and handling log events.
47
  /// - [focusManager] - delegate for managing UI element focus.
48
  ///   Controls keyboard navigation through elements.
49
  /// - [actionManager] - delegate for executing server actions.
50
  ///   Handles server-specific commands.
51
  /// - [controllerManager] - delegate for managing UI controllers.
52
  ///   Manages widget state (e.g., TextField).
53
  /// - [viewManager] - delegate for managing view models.
54
  ///   Manages view state and data.
55
  ///
56
  /// Example:
57
  /// ```dart
58
  /// final driver = XDriver.remote(
59
  ///   transportManager: HttpTransportManager(
60
  ///     baseUrl: 'https://api.example.com',
61
  ///   ),
62
  ///   initialRequestPayload: {
63
  ///     'userId': '12345',
64
  ///     'theme': 'dark',
65
  ///   },
66
  ///   loggingManager: CustomLogger(),
67
  /// );
68
  /// ```
NEW
69
  factory XDriver.remote({
×
70
    required TransportCapabilityDelegate transportManager,
71
    Map<String, dynamic>? initialRequestPayload,
72
    NativeModuleCapabilityDelegate? nativeModuleManager,
73
    ScriptingCapabilityDelegate? scriptingManager,
74
    LoggingCapabilityDelegate? loggingManager,
75
    FocusCapabilityDelegate? focusManager,
76
    ServerActionExecutionCapabilityDelegate? actionManager,
77
    UIControllerCapabilityDelegate? controllerManager,
78
    ViewModelCapabilityDelegate? viewManager,
79
  }) =>
NEW
80
      XDriver._(
×
NEW
81
        DuitDriverCompat(
×
82
          isModule: false,
83
          initialRequestPayload: initialRequestPayload,
84
          transportManager: transportManager,
85
          nativeModuleManager: nativeModuleManager,
86
          scriptingManager: scriptingManager,
87
          loggingManager: loggingManager,
88
          focusManager: focusManager,
89
          actionManager: actionManager,
90
          controllerManager: controllerManager,
91
          viewManager: viewManager,
92
        ),
93
      );
94

95
  /// Creates a driver for working with static JSON content.
96
  ///
97
  /// This constructor is used when the UI is predefined and does not require
98
  /// server connection. Ideal for offline mode, testing,
99
  /// or applications with fixed UI.
100
  ///
101
  /// **Required parameters:**
102
  /// - [content] - JSON structure with UI description according to Duit specification.
103
  ///   Cannot be empty, otherwise [StateError] will be thrown.
104
  ///
105
  /// **Optional parameters:**
106
  /// - [initialRequestPayload] - initial data for initialization.
107
  ///   Can be used by scripts or actions in the UI.
108
  /// - [nativeModuleManager] - delegate for managing native modules.
109
  ///   Allows calling platform-specific code.
110
  /// - [transportManager] - optional transport manager.
111
  ///   If not specified, [StubTransportManager] stub is used.
112
  ///   Can be useful for hybrid scenarios.
113
  /// - [scriptingManager] - delegate for executing scripts.
114
  ///   Allows adding dynamic logic to static UI.
115
  /// - [loggingManager] - delegate for customizing logging.
116
  /// - [focusManager] - delegate for managing UI element focus.
117
  /// - [actionManager] - delegate for executing actions.
118
  /// - [controllerManager] - delegate for managing UI controllers.
119
  /// - [viewManager] - delegate for managing view models.
120
  ///
121
  /// **Throws:**
122
  /// - [StateError] if [content] is empty.
123
  ///
124
  /// Example:
125
  /// ```dart
126
  /// final uiContent = {
127
  ///   'type': 'Column',
128
  ///   'children': [
129
  ///     {'type': 'Text', 'data': 'Hello World'},
130
  ///   ],
131
  /// };
132
  ///
133
  /// final driver = XDriver.static(
134
  ///   uiContent,
135
  /// );
136
  /// ```
137
  factory XDriver.static(
348✔
138
    Map<String, dynamic> content, {
139
    Map<String, dynamic>? initialRequestPayload,
140
    NativeModuleCapabilityDelegate? nativeModuleManager,
141
    TransportCapabilityDelegate? transportManager,
142
    ScriptingCapabilityDelegate? scriptingManager,
143
    LoggingCapabilityDelegate? loggingManager,
144
    FocusCapabilityDelegate? focusManager,
145
    ServerActionExecutionCapabilityDelegate? actionManager,
146
    UIControllerCapabilityDelegate? controllerManager,
147
    ViewModelCapabilityDelegate? viewManager,
148
  }) {
149
    if (content.isEmpty) {
348✔
150
      // throw StateError(
151
      //   "[content] property must be valid Duit json struct",
152
      // );
153
    }
154
    return XDriver._(
348✔
155
      DuitDriverCompat(
348✔
156
        content: content,
157
        initialRequestPayload: initialRequestPayload,
158
        isModule: false,
159
        transportManager: transportManager ?? StubTransportManager(),
348✔
160
        nativeModuleManager: nativeModuleManager,
161
        scriptingManager: scriptingManager,
162
        loggingManager: loggingManager,
163
        focusManager: focusManager,
164
        actionManager: actionManager,
165
        controllerManager: controllerManager,
166
        viewManager: viewManager,
167
      ),
168
    );
169
  }
170

171
  /// Creates a driver for native module mode.
172
  ///
173
  /// This constructor is used when Duit is integrated as a module
174
  /// into an existing Flutter application. The driver works with a native
175
  /// transport layer for interaction with the host application.
176
  ///
177
  /// In this mode, [NativeTransportManager] is used by default,
178
  /// which provides communication between Duit UI and native code
179
  /// of the application through platform channels or other mechanisms.
180
  ///
181
  /// **Optional parameters:**
182
  /// - [initialRequestPayload] - initial data from the host application.
183
  ///   May contain context, configuration parameters, etc.
184
  /// - [nativeModuleManager] - delegate for managing native modules.
185
  ///   Critical for interaction with the host application.
186
  /// - [transportManager] - custom transport manager.
187
  ///   If not specified, [NativeTransportManager] is used by default.
188
  /// - [scriptingManager] - delegate for executing scripts.
189
  ///   Allows extending module logic.
190
  /// - [loggingManager] - delegate for customizing logging.
191
  ///   Can integrate with the host application's logging system.
192
  /// - [focusManager] - delegate for managing UI element focus.
193
  /// - [actionManager] - delegate for executing actions.
194
  ///   Can handle specific commands from the host application.
195
  /// - [controllerManager] - delegate for managing UI controllers.
196
  /// - [viewManager] - delegate for managing view models.
197
  ///
198
  /// Example:
199
  /// ```dart
200
  /// final driver = XDriver.nativeModule(
201
  ///   nativeModuleManager: MyNativeModuleManager(),
202
  ///   initialRequestPayload: {
203
  ///     'hostVersion': '1.0.0',
204
  ///     'features': ['analytics', 'payments'],
205
  ///   },
206
  /// );
207
  /// ```
NEW
208
  factory XDriver.nativeModule({
×
209
    Map<String, dynamic>? initialRequestPayload,
210
    NativeModuleCapabilityDelegate? nativeModuleManager,
211
    TransportCapabilityDelegate? transportManager,
212
    ScriptingCapabilityDelegate? scriptingManager,
213
    LoggingCapabilityDelegate? loggingManager,
214
    FocusCapabilityDelegate? focusManager,
215
    ServerActionExecutionCapabilityDelegate? actionManager,
216
    UIControllerCapabilityDelegate? controllerManager,
217
    ViewModelCapabilityDelegate? viewManager,
218
  }) =>
NEW
219
      XDriver._(
×
NEW
220
        DuitDriverCompat(
×
221
          isModule: true,
222
          initialRequestPayload: initialRequestPayload,
NEW
223
          transportManager: transportManager ?? NativeTransportManager(),
×
224
          nativeModuleManager: nativeModuleManager,
225
          scriptingManager: scriptingManager,
226
          loggingManager: loggingManager,
227
          focusManager: focusManager,
228
          actionManager: actionManager,
229
          controllerManager: controllerManager,
230
          viewManager: viewManager,
231
        ),
232
      );
233

234
  /// Creates an [XDriver] from an existing [UIDriver] instance.
235
  ///
236
  /// This constructor is intended for internal library use only.
237
  /// It allows wrapping an existing [UIDriver]
238
  /// in the public [XDriver] API.
239
  ///
240
  /// **Parameters:**
241
  /// - [driver] - existing [UIDriver] instance to wrap.
242
  ///
243
  /// **Warning:** Marked as [@internal] and should not be used
244
  /// in user code. Intended only for internal
245
  /// library implementation.
246
  @internal
132✔
247
  factory XDriver.from(UIDriver driver) => XDriver._(
396✔
248
        driver,
249
      );
250

251
  /// Registers an external event handler.
252
  ///
253
  /// Allows attaching custom event handling logic
254
  /// defined on the server side or in the UI description. External handlers
255
  /// are called when the UI generates events not handled by standard
256
  /// Duit logic.
257
  ///
258
  /// **Parameters:**
259
  /// - [type] - event handler type identifying the event category.
260
  ///   Determines which events will be routed to this handler.
261
  /// - [handle] - event handler function.
262
  ///   Accepts event data and executes necessary logic.
263
  ///
264
  /// Handlers are called synchronously when a corresponding
265
  /// event occurs in the UI. One type can have only one handler; re-registration
266
  /// replaces the previous handler.
267
  ///
268
  /// Example:
269
  /// ```dart
270
  /// driver.attachExternalHandler(
271
  ///   UserDefinedHandlerKind.custom('onButtonClick'),
272
  ///   (eventData) {
273
  ///     print('Button clicked: ${eventData['id']}');
274
  ///     // Handle click
275
  ///   },
276
  /// );
277
  /// ```
NEW
278
  @preferInline
×
279
  void attachExternalHandler(
280
    UserDefinedHandlerKind type,
281
    UserDefinedEventHandler handle,
282
  ) =>
NEW
283
      _driver.attachExternalHandler(type, handle);
×
284

285
  /// Adds an external event stream for driver processing.
286
  ///
287
  /// Allows integrating external event sources (e.g., WebSocket,
288
  /// Firebase, native platform events) into the Duit event handling system.
289
  /// Events from the stream will be automatically processed and can trigger
290
  /// UI updates or execution of registered handlers.
291
  ///
292
  /// **Parameters:**
293
  /// - [stream] - event stream in JSON format (Map<String, dynamic>).
294
  ///   Each event should contain necessary fields for identification
295
  ///   and processing (e.g., 'type', 'action', 'payload').
296
  ///
297
  /// The driver automatically subscribes to the stream when added and
298
  /// unsubscribes when [dispose] is called. Multiple streams can be added,
299
  /// and they will all be processed in parallel.
300
  ///
301
  /// **Important:** Ensure that the event structure matches the expected
302
  /// Duit format or is handled by registered external handlers.
303
  ///
304
  /// Example:
305
  /// ```dart
306
  /// final websocketStream = WebSocketChannel.connect(
307
  ///   Uri.parse('ws://example.com'),
308
  /// ).stream.map((data) => jsonDecode(data));
309
  ///
310
  /// driver.addExternalEventStream(websocketStream);
311
  /// ```
312
  @preferInline
4✔
313
  void addExternalEventStream(
314
    Stream<Map<String, dynamic>> stream,
315
  ) =>
316
      _driver.addExternalEventStream(
4✔
317
        stream,
318
      );
319

320
  /// Initializes the driver and prepares it for work.
321
  ///
322
  /// This method must be called before using the driver.
323
  /// Performs the following operations:
324
  /// - Transport layer initialization
325
  /// - Loading initial UI content (for remote mode)
326
  /// - Setting up all registered delegates and managers
327
  /// - Preparing the event system
328
  ///
329
  /// For remote drivers, the first request to the server is made
330
  /// using [initialRequestPayload] (if specified).
331
  ///
332
  /// **Returns:** [Future<void>] that completes when the driver
333
  /// is fully ready to work.
334
  ///
335
  /// **Throws:** May throw exceptions related to network errors,
336
  /// incorrect data format, or initialization problems.
337
  ///
338
  /// **Important:** Call this method only once. Repeated calls
339
  /// may lead to unpredictable behavior.
340
  ///
341
  /// Example:
342
  /// ```dart
343
  /// final driver = XDriver.remote(
344
  ///   transportManager: myTransport,
345
  /// );
346
  ///
347
  /// try {
348
  ///   await driver.init();
349
  ///   print('Driver is ready');
350
  /// } catch (e) {
351
  ///   print('Initialization error: $e');
352
  /// }
353
  /// ```
354
  @preferInline
340✔
355
  Future<void> init() async => _driver.init();
340✔
356

357
  /// Releases resources used by the driver.
358
  ///
359
  /// This method should be called when the driver is no longer needed.
360
  /// Performs the following cleanup operations:
361
  /// - Closing transport connections
362
  /// - Canceling subscriptions to external event streams
363
  /// - Clearing internal caches and state
364
  /// - Releasing resources of all registered managers
365
  /// - Removing all event handlers
366
  ///
367
  /// **Important:** After calling [dispose], the driver becomes unusable.
368
  /// Attempting to call driver methods after dispose
369
  /// may lead to errors.
370
  ///
371
  /// It is recommended to call this method in the dispose method of the widget
372
  /// using the driver to avoid memory leaks.
373
  ///
374
  /// Example:
375
  /// ```dart
376
  /// class MyWidget extends StatefulWidget {
377
  ///   @override
378
  ///   State<MyWidget> createState() => _MyWidgetState();
379
  /// }
380
  ///
381
  /// class _MyWidgetState extends State<MyWidget> {
382
  ///   late final XDriver driver;
383
  ///
384
  ///   @override
385
  ///   void initState() {
386
  ///     super.initState();
387
  ///     driver = XDriver.remote(...);
388
  ///     driver.init();
389
  ///   }
390
  ///
391
  ///   @override
392
  ///   void dispose() {
393
  ///     driver.dispose();
394
  ///     super.dispose();
395
  ///   }
396
  ///
397
  ///   @override
398
  ///   Widget build(BuildContext context) => ...;
399
  /// }
400
  /// ```
401
  @preferInline
4✔
402
  void dispose() => _driver.dispose();
4✔
403

404
  /// Provides access to the internal [UIDriver] instance.
405
  ///
406
  /// This getter is intended for internal library use only.
407
  /// It allows getting direct access to the wrapped
408
  /// [UIDriver] for cases when interaction between
409
  /// internal system components is necessary.
410
  ///
411
  /// **Returns:** Internal [UIDriver] instance.
412
  ///
413
  /// **Warning:** Marked as [@internal] and should not be used
414
  /// in user code. Direct use of [UIDriver] may
415
  /// break encapsulation and lead to unpredictable behavior.
416
  /// Use public [XDriver] methods for all operations.
417
  @internal
348✔
418
  @preferInline
419
  UIDriver get asInternalDriver => _driver;
420
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc