Support latest Dart/Flutter and Meteor 3.5.1 - #74
Merged
Conversation
- Bump minimum SDK to Dart 3.6, tested with Dart 3.13 (latest stable). - Release 4.0.0 including web support from the 4.0.0 betas. - Update dependency floors and lints to lints 6; fix all analyzer issues. - Rename DdpClient.PING_SEC_INTERVAL/PONG_WITHIN_SEC to static constants pingIntervalSeconds/pongTimeoutSeconds (breaking). - Add a standalone DDP protocol test suite backed by an in-process mock server speaking DDP version 1 as Meteor 3.5.1 does (handshake, ping/pong, methods, EJSON $date, SHA-256 login, subscriptions, reconnect) so core behavior is testable without docker or a live Meteor server. - Exclude the Flutter example from root package analysis and mark it publish_to: none; bump example to flutter_lints 6. - Modernize CI: dart-lang/setup-dart, analyze + protocol tests before the docker-based integration tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N1hm1DRToNVwU4D6wtJAt3
Restructure into installation, quick start, methods, subscriptions, accounts, connection management, and upgrade notes. Modernize code samples (null safety, ElevatedButton, async/await error handling) and fold the old per-version change notes into a compact Upgrading section. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N1hm1DRToNVwU4D6wtJAt3
Explicitly list android, ios, linux, macos, web, and windows so pub.dev shows the full platform support instead of inferring it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N1hm1DRToNVwU4D6wtJAt3
Rebuild the example as a Simple Meteor Chat client that runs on iOS, Android and Web against the live demo server, replacing the old scaffold. Restructure the Android and iOS projects (new application id dev.tanutapi.dart_meteor_example, Kotlin/Swift entry points, SceneDelegate) and drop generated files that do not belong in version control. Rewrite the package README around the current API: quick start, method calls, subscriptions and collections, accounts, connection management and error handling. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A device that sleeps suspends the process: timers stop firing and the server drops the session without the socket ever reporting an error. The client handled none of that well. - A missed pong left the client permanently offline. The pong timeout called disconnect(), which also disabled reconnection, so no retry was ever scheduled - the exact path a device takes when it wakes with a stale socket. Split the user-initiated disconnect() from an internal connection-lost path that always schedules a retry. - Reconnect backoff never engaged: retryCount was reset on every attempt, so the interval was always 0s and maxRetryCount was never reached. Reset it only once the server accepts the connection. - Connecting to an unreachable server raised an unhandled exception that could terminate the application, because WebSocketChannel.connect fails asynchronously rather than throwing. Await ready and route the failure into the normal retry path. - In-flight method calls never completed when the connection dropped. They now complete with the new MeteorConnectionError. Calls are not resent, since methods are not necessarily idempotent. - Subscriptions were re-sent before the login token was resumed, so publications depending on this.userId re-ran unauthenticated after every reconnect. Re-subscription now awaits the onReconnect callbacks. - disconnect() did not cancel a pending reconnect timer, so an explicit disconnect could be undone by an already-scheduled retry. - status() emitted the client's own mutable object, so fast transitions could be misread by subscribers. Each event is now a snapshot. Add notifyAppPaused()/notifyAppResumed()/checkLiveness(). On resume the client compares the wall clock against the last message received and replaces a stale connection immediately instead of waiting for a ping to time out. The package stays pure Dart; the Flutter WidgetsBindingObserver glue is a few lines, shown in the README and wired into the example app. Ping, pong, backoff and staleness durations are now configurable. Add test/lifecycle_test.dart, a server-free regression suite for all of the above, and run it in CI. The mock DDP server moves to test/mock_ddp_server.dart so both suites share it. In the integration suite, await the reactive user document instead of reading it synchronously after login (it arrives ~30ms later, as a separate DDP message) and guard completers that a stream can fire more than once. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
pingIntervalSeconds/pongTimeoutSeconds (breaking).
server speaking DDP version 1 as Meteor 3.5.1 does (handshake, ping/pong,
methods, EJSON $date, SHA-256 login, subscriptions, reconnect) so core
behavior is testable without docker or a live Meteor server.
publish_to: none; bump example to flutter_lints 6.
docker-based integration tests.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01N1hm1DRToNVwU4D6wtJAt3