Dart and Flutter
This specification applies to the Dart/Flutter SDK in sdk/flutter/gizclaw and the Flutter App in apps/gizclaw-app. The SDK has GizClaw contract, transport and reusable client capabilities; the App is responsible for product UI, page status and platform integration, and cannot copy the protocol implementation already provided by the SDK.
Dart basic rules
- Use the standard format generated by
dart formatand do not manually maintain formatting that conflicts with the formatter. - SDK follows
package:lints/recommended.yaml, App followspackage:flutter_lints/flutter.yaml; the new lint suppression must be limited to the minimum scope and the reason must be explained. - library, file, variable and function use
lower_snake_caseorlowerCamelCasecorresponding Dart official convention; type, enum and extension useUpperCamelCase. - Keep symbols private by default and only export stable surfaces that SDK users actually need. Public APIs are uniformly exposed from
lib/gizclaw.dart, and callers should not rely onlib/src/. - Immutable value is preferred to
final; only use mutable variables when reassignment is absolutely necessary. - Do not use
dynamicor unchecked cast to bypass the bounds check of external payload, platform channel and generated message.
SDK Boundaries
- OpenAPI, Protobuf and RPC Schema are the source of truth for generating Dart messages and registry methods;
lib/src/generated/can only be updated by the generation process. - The signaling, WebRTC transport, RPC frame and payload codec each maintain a single responsibility and do not reassemble the protocol frame or duplicate the method name in the App.
- SDK public methods should return stable Dart types and clearly express error, cancellation, and shutdown semantics; do not unnecessarily leak internal types of providers, WebRTC plugins, or generated code to the app.
- The stream must define subscription, error, done, and cancellation behaviors. The owner who created the
StreamController, peer connection, data channel or subscription must also be responsible for closing it. Futuremust beawait, returned, or handled explicitly; errors in asynchronous callbacks cannot be lost silently.- Network, RPC, signaling, and codec inputs are considered untrusted and must handle malformed frames, unknown methods, bad payloads, repeated closes, and connection interruptions.
Flutter App
- Widget is only responsible for display and interaction; protocol, transport, retry and resource resolution should be left in the SDK or explicit application service.
- The controller, subscription, animation, timer and SDK connection created by
Statemust be released by ownership indispose. - After
awaitvisitBuildContextor checkmountedbefore callingsetStateto avoid updates after page destruction. - The page must have clear loading, empty, error, success, offline and permission-denied status, and cannot use infinite loading to hide failure.
- Build methods remain side-effect-free; network requests, subscription creation, and persistence writes cannot be implicitly triggered by repeated builds.
- Platform-specific behavior is managed through explicit adapter or plugin boundaries, and differences are verified for Android, iOS and test environments respectively.
- Interactive components should provide stable semantics, clickable scope, disabled state, focus/keyboard behavior, and testable widget keys or semantics.
Status and data flow
- The source of truth for a state must be unique. Widget local state only saves the local display state, and the connection, session and shared resource states are managed by its explicit owner.
- Do not pass
BuildContext, Widget orStateobjects into the SDK. - For real-time streams, the processing methods of ordering, reconnect, duplicate event, terminal state and backpressure should be clarified.
- Expensive decoding, audio and video conversion or large resource processing cannot block UI isolate; use isolate or native/plugin capabilities when necessary, and define cancellation and resource release.
Testing and Verification
- SDK test covers signaling, frame, codec, method registry, transport, error path and connection closure.
- Widget test covers asynchronous callbacks after loading, error, empty, interaction and destruction; use integration test when real plugin or platform life cycle is involved.
- Rerun the generation tool after changes in Schema or generated code, and confirm that the generated diff is consistent with the source contract.
- Run when modifying the SDK:
sh
dart format sdk/flutter/gizclaw
flutter analyze sdk/flutter/gizclaw
flutter test sdk/flutter/gizclaw- Run when modifying the app:
sh
dart format apps/gizclaw-app
flutter analyze apps/gizclaw-app
flutter test apps/gizclaw-app