4.13 Flutter Improvements - Support for Windows
Ditto 4.13 brings full support for Windows desktop applications in Flutter, expanding the range of platforms where you can deploy Ditto-powered apps.What’s New
The Flutter SDK now includes native Windows support, allowing you to build desktop applications that leverage Ditto’s sync capabilities on Windows platforms.Getting Started
Windows support works seamlessly with your existing Flutter Ditto integration. Simply target Windows as a build platform and Ditto will work as expected with all the features you’re already using on other platforms, including:- Local data persistence
- Peer-to-peer sync over LAN
- Cloud sync via the Big Peer
- DQL queries and observers
- Attachments
4.13 - DQL Index Enhancements, Observability & Performance
DQL INDEX Support for Union & Intersect Scans
Ditto 4.13 introduces advanced index utilization for complex query predicates, enabling significant performance improvements for local queries and observer registrations.What’s Available
The query optimizer can now leverage indexes when evaluating queries withOR, IN, and AND operators through union and intersect scans:-
Union Scans: When using
ORorINoperators, the query engine can now use multiple indexes simultaneously, combining results from each index scan. For example, a query likeWHERE status = 'active' OR priority = 'high'can use separate indexes on bothstatusandpriorityfields. -
Intersect Scans: For queries with multiple
ANDconditions, the engine can use multiple indexes and intersect their results, efficiently narrowing down matches. For example,WHERE category = 'urgent' AND assignee = 'user123'can leverage indexes on both fields.
Performance Impact
These optimizations can dramatically reduce query execution time for complex predicates, especially on large datasets. Instead of scanning entire collections, Ditto now uses indexes to quickly locate relevant documents.Query Selectivity MattersThe performance improvement from these index optimizations is inversely related to the selectivity of your query—that is, the percentage of documents returned:- Highly selective queries (returning a small percentage of documents) see the most dramatic improvements. For example, a query that returns only 10% of a collection can be approximately 90% faster, as the index allows skipping the other 90% of documents entirely.
- Less selective queries (returning a large percentage of documents) benefit less from indexes, since most documents still need to be examined.
Usage Example
Here’s how union scans work in practice. First, create indexes on the fields you’ll query:OR condition and use EXPLAIN to see the query plan:unionScan operator that leverages both indexes:EXPLAIN Result
unionScan operator combines results from both indexScan operations—one scanning the movies_runtime index for documents with runtime > 200, and another scanning the movies_year index for documents where _id.year = 2000. This is significantly faster than scanning the entire collection.Scope & Limitations
This optimization applies to:- Local DQL queries (
store.execute(...)) - Observer registrations (
store.registerObserver(...))
- Sync subscriptions (which use a different evaluation mechanism)
Data Sync Performance Improvements
Ditto 4.13 includes significant optimizations for peer-to-peer sync reconnection scenarios, particularly when peers have accumulated changes while disconnected.Intelligent Session Resync
When two previously synced peers reconnect after a period of disconnection, Ditto now intelligently detects when a full session resync (summary re-exchange) is more efficient than sending incremental updates. This avoids transmitting large, redundant diff-bearing updates that can slow down the sync process.Key improvements:- Backlog-based detection: The sync engine now tracks the size of pending changes (diff backlog) and automatically triggers session resync when the backlog exceeds a configurable threshold
- Faster reconnection: By requesting a fresh session basis instead of sending accumulated diffs, peers can resynchronize more efficiently when they’ve been apart for extended periods
- Reduced redundant data transfer: Eliminates unnecessary transmission of large update files containing redundant document changes
- Configurable threshold: A new system parameter allows tuning when session resync should be triggered based on your application’s sync patterns
- Mobile devices reconnect after extended offline periods
- Network interruptions cause peers to accumulate substantial local changes
- Peers with large datasets reconnect after diverging significantly
New System Collection: system:system_info
Ditto 4.13 introduces a new read-only system collection system:system_info that provides diagnostic and observability data about your Ditto instance. This collection logs key-value pairs with timestamps, allowing you to query runtime information, configuration, and performance metrics.What’s Available
Thesystem:system_info collection tracks various categories of information:SDK Metadata
SDK Metadata
SDK version, commit hash, language, and platform
Filesystem Metrics
Filesystem Metrics
Total device storage and available space, plus storage usage broken down by component (store, attachments, replication, auth)
Transport Configuration
Transport Configuration
Complete snapshot of enabled transports and their settings, connection endpoints (WebSocket URLs, TCP servers), and peer-to-peer transport settings (Bluetooth LE, LAN, AWDL, etc.)
System Parameters
System Parameters
Non-default configuration parameters and collection sync scopes
Store Metrics
Store Metrics
Document counts per collection
Active Subscriptions
Active Subscriptions
Local observer subscriptions currently registered
Connectivity
Connectivity
Active peer connections by transport type (Bluetooth, LAN, P2P WiFi, WebSocket, Access Point), cloud connection status, and device name
Logging Configuration
Logging Configuration
Whether logging is enabled and minimum log level
Eviction on Deleted Documents (Reaper)
Eviction on Deleted Documents (Reaper)
Last reaper execution time and number of tombstones reaped
Usage
Query the collection using standard DQL:Additional Improvements
Connection & Network Reliability
- Smarter logging: Connection failures now use adaptive log levels, starting at warning and escalating to error only after repeated failures, reducing log noise during temporary network issues
- Parallel connections: TCP client now attempts to connect to all discovered addresses in parallel for faster, more reliable connections
- mDNS optimization: mDNS now only advertises connectable addresses based on TCP server binding configuration
- Callback handling: Fixed issue where long-running connection callbacks could cause timeout failures
Attachment Access Improvements
- Fixed attachment retrieval: Resolved an issue where attachment requests would sometimes fail to resolve even when the attachment was available locally, making attachment access more reliable
Bug Fixes & Stability
- Fixed memory leak in disk usage monitoring
- Fixed bug causing small peers to re-upload logs on every startup
- Fixed post-eviction cleanup to properly retain metadata for non-evicted documents in disconnected sync sessions
- Improved logging for document deserialization errors
4.13 Full Change Log
Flutter Specific Changes
Flutter Specific Changes
Added: Support for Windows Platform Fixed: crash when force-closing iOS apps (#SDKS-1652)
Common Changes
Common Changes
Fixed: disk usage monitoring no longer leaks memory. (#18531) Changed: Connection failures now use smart log levels, starting at warning and escalating to error only after repeated failures. (#18779) Changed: mDNS now only advertises connectable addresses based on TCP server binding address. TCP Client now attempts to connect to all addresses in parallel (#18930) Changed: the default value of
ENABLE_ATTACHMENT_PERMISSION_CHECKS store configuration parameter to false (#18931) Added: system:system_info virtual collection for DQL access to system info (#CORE-751) Fixed: A bug that caused small peers to re-upload remotely requested logs on every startup (#CORE-810)Performance: Document sync avoids sending large, redundant updates after reconnecting a long-dormant session between two peers that are otherwise well-synced with the mesh. (#DS-433) Changed: Improved avoidance of large redundant doc sync updates after session reconnect, based on the number of diffs sent in the initial post-reconnect update. (#DS-475) Fixed: Post eviction cleanup of disconnected document sync sessions now retains metadata for non-evicted documents. (#DS-487) Added: Improved logging for document deserialization errors (#DS-568) Added: UNION & INTERSECT scans. (#QE-398) Added: Index support for array-based IN and NOT IN filter expressions in DQL queries. (#QE-417) Fixed: A long-running on connecting callback no longer causes ReceiveTimeout failures in connectivity. (#TRAN-729)4.12.4 Flutter Specific Changes
Fixed: crash when force-closing iOS apps (#SDKS-1652)4.12.4 Common Changes
Fixed: disk usage monitoring no longer leaks memory. (#18531) Changed: mDNS now only advertises connectable addresses based on TCP server binding address. TCP Client now attempts to connect to all addresses in parallel. (#18930) Fixed: a bug that caused small peers to re-upload remotely requested logs on every startup. (#CORE-810)4.12.3 Common Changes
Changed: Enabled opentelemetry tracing in core. (#18464) Fixed: An issue where peers could fail to connect other local peers via mDNS on macOS. (#18488) Fixed: a bug that meant document id indexes were not created. (#18512) Fixed: Document sync session metadata became unlinked after session reset. (#DS-509) Added: Improved logging for document deserialization errors. (#DS-568) Added: query vitals. (#QE-296) Fixed: Performance of the DQL parser for large statements. (#QE-321) Fixed: Issue with planner picking an index when anOR is present in a statement’s predicate leading to partial results. (#QE-373) Fixed: Planner not selecting an index for _id field filters. (#QE-374) Fixed: Android devices that fail to acquire an IP address will now continue to sync over LAN. (#TRAN-725) Fixed: A long-running on-connecting callback no longer causes ReceiveTimeout failures in connectivity. (#TRAN-729)4.12.2 Common Changes
Added: Explicit log flushing before aborting due to panic (#CORE-723) Changed: on-disk log file limits now apply to the compressed size, significantly increasing log retention (#CORE-729) Fixed: A rare scenario where an attachment fetch could be delayed by up to 60 seconds. (#DS-461) Added: query vitals (#QE-296) Fixed: use deterministic summaries for documents created by observers (#QE-310)4.12.1 Common Changes
Fixed: A bug where x509 refresh could speed up uncontrollably. (#17947) Fixed: A bug where a peer could get stuck with incorrect connection information. (#17967) Added:ENABLE_ATTACHMENT_PERMISSION_CHECKS ALTER SYSTEM parameter to be set to false to avoid certain rare cases of attachment fetcher hanging (#18016) Fixed: Network connections close gracefully when Ditto is stopped. (#18053) Fixed: The system:data_sync_info collection may briefly report sync immediately after connecting (#18137)Other: improve error reporting for document (de)serialization (#18165) Fixed: Live queries being unable to use indices. (#DS-447) Fixed: Use of DISTINCT with ORDER BY & OFFSET/LIMIT. (#QE-281)4.12 - DQL Enhancements & Platform Expansion
Version 4.12 brings significant enhancements to DQL (Ditto Query Language) with production-ready projections and aggregates, expanded platform support with Flutter for Linux and macOS, and marks the deprecation of legacy query builder APIs in preparation for DQL as the primary interface.DQL Projections & Aggregates
DQL projections and aggregates are now out of preview and fully production-ready. These powerful features enable sophisticated data analysis and optimized query performance directly within DQL.Projections
Select specific fields and create calculated columns to reduce data transfer and processing:DQL
Aggregate Functions
Perform calculations across multiple documents with SQL-standard aggregate functions:DQL
DQL Index Management
Create and manage indexes directly through DQL for improved query performance:DQL
Flutter Platform Expansion
Linux Support
Flutter developers can now build and deploy Ditto-powered applications on Linux desktops:- Native Linux binary (
libdittoffi.so) included - Full support for development, testing, and production deployments
- Configurable binary path via
$LIBDITTOFFI_PATHenvironment variable - Compatible with Flutter’s standard Linux development workflow
Legacy Query Builder Deprecation
The entire legacy query builder API is deprecated across all SDKs. Developers should migrate to DQL for all data operations:Migration Benefits:- SQL-like syntax familiar to developers
- Unified interface for all data operations
- Better performance and optimization
- More powerful query capabilities
Additional Enhancements
System Improvements
- Enhanced disk observer: Now enabled at startup with configurable batch settings
- Improved error handling: Better error propagation and syntax error identification in DQL
- Memory optimizations: Reduced memory usage for aggregate operations and projections
DQL Function Additions
- Duration scalar functions for date/time calculations
- Dynamic field references in queries
- Support for arrays as operation values
- Extended multiplication operations for better numeric handling
Security & Diagnostics
- Support for
SSLKEYLOGFILEfor debugging TLS connections - New
system::data_sync_infovirtual collection for sync diagnostics - Transport diagnostics APIs across multiple SDKs
Upgrading to 4.12
To take advantage of these new features:- Update your SDK to version 4.12.0 or later
- Begin migrating legacy query builder code to DQL
- Explore projections and aggregates for query optimization
- Consider Flutter Linux support for desktop deployments
Version 4.12 maintains full backward compatibility while encouraging migration to modern DQL APIs. Legacy APIs continue to function but should be replaced in preparation for SDK v5.
4.12.0 Common Changelog
Added
- The
transports_discovered_peerssystem parameter to dynamically update peers discovered out-of-band (#17009) - The new
system::indexesvirtual collection for viewing DQL indexes on small peers (#17011) - Support for
SSLKEYLOGFILEfor inspecting network traffic in tools like Wireshark (#17029) UPDATE_LOCAL_DIFFid conflict strategy for INSERT statements (#17310)- A system:data_sync_info virtual collection that exposes per-remote data sync status via DQL (#17360)
transports_tcp_so_nodelaysystem parameter to control TCP_NODELAY for TCP and TCP-based websockets connections (#17673)- Additional metadata to keep track of the timestamp of the last update file received (#DS-290)
- Observers for DQL queries can now access system virtual collections (#DS-294)
- Query executor runner to observers - they now support all of the new DQL features like projections, aggregates, use ids… (#QE-143)
- SYSTEM:COLLECTIONS & SYSTEM:ALL_COLLECTIONS virtual collections to list accessible collections (#QE-146)
- Support for ARRAYs as the value options list in IN DQL expressions (#QE-167)
- DQL scalar functions for durations (#QE-170)
- DQL support for CREATE INDEX (#QE-182)
- DQL support for DROP INDEX (#QE-183)
- Support for dynamic field references in DQL statements (#QE-2)
- Query request history cache qualifiers for system datasource deletes and general mutations (#QE-207)
- Basic RBO for index scan selection (#QE-210)
- Query parser handles context dependent keyword (#QE-241)
- Virtual collections for active and historical DQL engine requests (#QE-82)
Changed
- device_disk_observer_is_enabled system parameter can now be changed at runtime (#CORE-612)
- After eviction, document sync now retains high-level session metadata for non-expired sessions, for sync status tracking purposes (#DS-348)
- Projection, distinct and aggregate features out of preview mode! (#QE-100)
- Wildcard expansion to top-level with left-to-right, last-wins projection aliasing (#QE-156)
- Improved ScalarExpr representation in EXPLAIN output (#QE-193)
- Improved syntax error identification in UPDATE statements (#QE-199)
- ALTER SYSTEM DQL statements now accept static expressions (#QE-204)
- USE IDS clause to accept expressions that can be statically evaluated (#QE-217)
- Permit use of unary plus in DQL expressions (#QE-220)
- Extended DQL multiplication to better handle multiplying two large negative integers (#QE-224)
- Query directives processing to accept USE INDEX as the equivalent of USE DIRECTIVES
{"#index":...}(#QE-255) - CREATE & DROP INDEX statements accept IF [NOT] EXISTS to permit repeated execution without error (#QE-259)
- Websocket connectivity errors are now logged with additional detail (#TRAN-511)
- Ditto no longer includes a peer’s device name and OS during P2P advertisement (BLE, mDNS, Wi-Fi Aware, AWDL) (#TRAN-652)
Fixed
- A rare race condition which caused connection handshakes to erroneously fail (#17251)
- Merge tombstone summaries when applying remote tombstone (#17654)
- Set default TCP_NODELAY socket option to true to improve latency, notably on Linux (#17673)
- DQL collation order is based on length of arrays / objects, not padding values with extra MISSING (#QE-171)
- DQL scalar function clock() and “local” timezone in WASM environments (#QE-181)
- Error propagation from collection scans (#QE-191)
- Collation in DQL aggregates (#QE-216)
- Panic when using COUNT(*) in a dynamic object (#QE-219)
- Panic when subtracting a large positive integer value from a large negative integer value (#QE-223)
- Aggregate output on empty result sets (#QE-242)
Performance
- Revised fetching documents by ID in Query to operate in batches (#QE-248)
Other
- Added a warning to the log when a subscription query uses a LIMIT or ORDER BY (#QE-169)
4.12.0 Flutter Specific Changes
Added: Linux desktop support - Flutter developers can now build and deploy Ditto-powered applications on Linux (#17486) Added: Read-only propertycommitID to class QueryResult (#SDKS-1280) Added: Devtools extension to view the configuration and status of Ditto in Flutter applications (#17005)4.11.6 Common Changes
Fixed: disk usage monitoring no longer leaks memory. (#18531) Fixed: Document sync session metadata became unlinked after session reset. (#DS-509) Changed: Improved logging and error handling for handle_get_txid_query.4.11.5
4.11.5 Common Changes
Added: Explicit log flushing before aborting due to panic. Changed: On-disk log file limits now apply to the compressed size, significantly increasing log retention. Fixed: A rare scenario where an attachment fetch could be delayed by up to 60 seconds.Other: improve error reporting for document (de)serialization4.11.5 Flutter Specific Changes
Fixed: A bug which caused the websocket retry interval to be higher than it should be.4.11.4
4.11.4 Common Changes
Fixed: A bug where x509 refresh could speed up uncontrollably. Fixed: A bug where a peer could get stuck with incorrect connection information.4.11.3 Common Changes
Fixed: An issue with BLE on some Android 9 and earlier devices that prevented connection establishment.4.11.2 Common Changes
Fixed: A rare race condition which caused connection handshakes to erroneously fail. Changed:device_disk_observer_is_enabled system parameter can now be changed at runtime.4.11 - DQL & Legacy Compatibility
With 4.11 we are excited to introduce legacy compatibility for DQL, which allows developers to use the new DQL APIs while maintaining compatibility with existing code and data. This capability, called STRICT MODE, is designed to ease the transition to the new APIs and ensure that existing applications continue to function as expected.DQL Strict Mode
DQL Strict Mode provides control over how DQL statements are evaluated and how data types are inferred. When disabled, it offers more flexibility in working with documents without requiring explicit collection definitions.With strict mode disabled (DQL_STRICT_MODE=false), Ditto is more flexible and will infer the CRDT type based on the document’s shape:- Objects are treated as CRDT maps
- Scalars and arrays are treated as Registers
- Counters and attachments are inferred from operations
- Collection definitions are no longer required
DQL
DQL Differ
DQL 4.11 introduces a newDiffer API for calculating diffs between query results.
This API can be used with a store observer to understand how its results change
over successive callbacks. The Differ API provides a way to track changes in
the data and can be used to optimize data synchronization and conflict resolution.Differ API documentation.DQL Transactions
DQL 4.11 introduces support for transactions. Transactions can be used to group multiple DQL statements together, ensuring that either all of the statements are executed successfully or none of them are. This is particularly useful in scenarios where multiple updates or inserts need to be made to the database, and you want to ensure that either all of them are applied or none of them are.Transactions API documentation.Advanced DQL Features
DQL 4.11 introduces numerous advanced querying and manipulation features:| Feature | Description | Example |
|---|---|---|
UNSET clause | Remove fields from documents | UPDATE orders UNSET items.abc WHERE _id = 'my-id' |
| CAST function | Explicitly convert between data types | SELECT * FROM products WHERE CAST(price AS INT) > 10 |
| USE IDS clause | Direct document retrieval by ID | SELECT * FROM products USE IDS '123', '456' |
| SIMILAR TO | Pattern matching expressions | SELECT * FROM products WHERE name SIMILAR TO '%phone%' |
| Runtime expressions | Use expressions in object/array construction | UPDATE products SET metadata = { 'updated_at': current_timestamp() } |
| Counters | Support for legacy compatible counter type | UPDATE products APPLY in_stock PN_INCREMENT BY 1.0 |
Tombstone Reaper
The tombstone reaper is now enabled by default for all SDKs. This feature helps clean up deleted document markers (tombstones) to improve database performance and reduce storage requirements.The reaper:- Automatically removes tombstones after a configurable time-to-live (TTL)
- Uses read transactions for efficiency
- Includes random scheduling variations to prevent performance problems
- Tracks the number of tombstones evicted for monitoring
- Remembers previous reap times across restarts
DELETE to remove documents.4.11.0 Common Changelog
Added
- Introduced
DQL_STRICT_MODEas a system parameter to opt-out of requiring collection definitions (#16573) - Added transports_ble_adapter_mac system parameter to allow configuring bluetooth adapter MAC address (#16159)
- Small peers now log the result of OnlinePlayground authentication, including if the supplied shared token was incorrect (#16301)
- A cumulative running total of the number of tombstones ever evicted by the reaper to Small Peer Info (#16424)
- Added system parameters to fine-tune Ditto behavior when it encounters a locked persistence directory (#CORE-479)
- New DQL CAST function to explicitly cast between types (#QE-108)
- Conditional functions for unknowns (#QE-111)
- DQL DATE processing functions (#QE-112)
- New DQL clause USE IDS for direct document retrieval by id (#QE-114)
- Additional string functions (#QE-124)
- SIMILAR TO filter expression (#QE-125)
- PN_COUNTER support (APPLY clause in UPDATE statement) (#QE-127)
- UNSET clause to the UPDATE statement (#QE-128)
- MERGE as an alias for UPDATE in the ON ID CONFLICT clause of an INSERT statement (#QE-132)
- The ability to use runtime-evaluated expressions in object constructs in DQL statements (#QE-133)
- The ability to use runtime-evaluated expressions in array constructs in DQL statements (#QE-134)
- Static expressions in mutators (#QE-139)
- Additional object manipulation DQL scalar functions (#QE-159)
- EXPLAIN for query plan (#QE-105)
- More detailed messages about network problems are logged when authentication fails (#SEC-124)
Changed
- Use the modern rustls-platform-verifier TLS crate on all platforms rather than rustls-native-certs (#15956)
- The tombstone reaper scheduling to remember the previous reap times across shutdown and restart of the small peer (#16237)
- The tombstone reaper scheduling code to add random variations, which helps prevent performance problems if/when all peers run the reaper simultaneously (#16286)
- The tombstone reaper to be enabled by default for all SDKs (#16350)
- INSERT to now accept either DOCUMENTS or VALUES as the keyword introducing the list of values to insert (#QE-140)
- Date functions accept “local” as a timezone & use the executing peer’s local timezone (#QE-168)
- Unified dedicated TCP servers across different transports (Multicast, mDNS, and WiFi Aware) by utilizing a single static TCP server implementation (#TRANS-131)
Fixed
- Fixed issue where user_collection_sync_scopes could not be updated after initial set (#16299)
- Fixed: A rare crash on Android devices when shutting down Bluetooth. (#17069)
- Fixed: Bluetooth connectivity on Apple devices works when background Bluetooth permissions are missing. (#17065)
Removed
- Old multihop networking stack and system parameter
network_use_nextgen_multihop_stack(#16370) - TLS certificate compression, which led to incompatibilities (#SDKS-1046)
Performance
- The tombstone reaper uses read transactions for some of its work instead of holding open a long-running write transaction, thus reducing contention on the small peer database (#16338)
- Improved speed and efficiency of the tombstone reaping process (#16535)
4.11.0 Flutter Specific Changes
- Added
DittoDiffclass to represent diffs produced by theDittoDiffer - Added
DittoDifferclass for calculating diffs between query results - Added
transaction()method onDittoStorefor performing DQL transactions - Added
DittoTransactionclass to represent an active DQL transaction - Added
DittoTransactionInfoclass for transaction information - Added
DittoTransactionCompletionActionfor commit/rollback actions
4.10.4 Security & Stability Improvements
We’ve enhanced our TLS certificate handling to provide more robust and reliable secure connections while maintaining our high security standards.- Improved reliability of secure connections by gracefully handling certificate validation challenges
- Enhanced network stability with smarter handling of security certificates
- Added flexibility in secure connection handling while maintaining robust security standards
4.10.3 Stability Improvements, DQL Enhancements
We’ve enhanced our query capabilities with improved sorting and filtering for UPDATE operations, while also focusing on overall reliability improvements.- Added powerful sorting and filtering capabilities to UPDATE operations, giving you more control over how you modify data on Small Peer devices
- Enhanced reliability and performance of data queries across your application
4.10.2
- No significant changes. Bumped version to 4.10.2 to align with other SDKs.
4.10.1
- Added support for the web platform
- Attachment fetchers now successfully complete the attachment fetch operation
- The
isStoppedproperty ofAttachmentFetcherinstances now becomestrueafter completing an attachment fetch - Resolved a memory leak that affected
QueryResultandQueryResultItem ditto.store.newAttachmentnow returns aFuture<Attachment>rather than an Attachmentditto.close()now returns aFuture<void>rather thanvoid
4.10.0 New Capabilities
Now Supporting Flutter 3.19+
Ditto’s Flutter SDK now supports Flutter 3.19 and later, broadening compatibility and making it easier for more developers to integrate Ditto into their apps. This update ensures greater flexibility, allowing teams to adopt Ditto without needing to upgrade immediately to the latest Flutter version.Experimental Support for Hot Restart in Flutter
The Ditto team is excited to preview support for Hot Restarts in Flutter.To allow users experiment and provide feedback on hot restarts we’ve shipped a specific SDK version with hot restarts enabled by default.To use hot restarts update your version to4.10.0-experimental-hot-restart.0. This version is identical to 4.10.0 but
has Hot Restart enabled by default. In a upcoming release this capability will be integrated into Ditto’s standard package
as a developer mode config that can be set by the user on Ditto class initialization.Flutter Dart has limited support for Hot Restarts with native binaries, such as Ditto. The Ditto team is working to mitigate
these issues. If you run into any issues while experimenting with Flutter Hot Restarts reach out to Ditto Customer Support.Known issues include:- Logging must be disabled. To do this set
DittoLogger.isEnabled = falseimmediately after callingawait Ditto.init(). - Attempting to use attachments will cause a crash.
- Hot restarting will leak some resources, notably memory. In our testing, approximately 20-30MB is leaked per hot-restart.
- Data integrity cannot be guaranteed. You may experience data corruption when hot-restarting, which may be propagated to any peers that are being synced with.
- Sporadic crashes can occur.
4.10.0 Flutter Specific Changelog
- Add support for Flutter 3.19 (Flutter - support 3.19 #16080)
- Throw an error when trying to use Ditto APIs before awaiting
Ditto.init()(#15880) - persistenceDirectory now supports relative paths and no longer needs to exist, and also works on web (#15890)
- compiling with —wasm now works. Required for upcoming Flutter Web release. (#15991)
- LAN transport shuts down when
stopSync()is called (#SDKS-707)
4.9.2
Fixed: Fixed a bug that caused observer events to not be triggered in profile and release mode (either via theonChange parameter
or the StoreObserver.changes stream)4.9.1
Added: Support for Flutter 3.19 for iOS and Android Changed: Failing to callawait Ditto.init() will now throw. This is to prevent improper initialization. Changed: ditto.transportsConfig = config; will now throw if config enables
transports which don’t exist on the current platform (e.g. AWDL on Android or P2P Wifi on iOS).TransportConfig.setAllPeerToPeerEnabled() will now take the current platform
into account, and will only modify transports which are available. A newly
created Ditto instance will not have transports enabled that are not
available on the current platform Fixed: Resolve an uncaught exception
that could happen in ditto.presence.graph when there were P2PWifi connections. Fixed: The persistence directory
behaves differently if a relative path is provided.If a relative path is provided, it will be treated as a subdirectory of
getApplicationDocumentsDirectory(). If an absolute path is given, its value
is not modified. The persistenceDirectory parameter in Ditto.open is now
optional, and defaults to "ditto". If the directory does not exist, it will be created.4.9.0 (GA Release)
We’re excited to announce the General Availability of the Ditto Flutter SDK! Designed to empower developers building cross-platform apps, the Flutter SDK delivers reliable real-time data synchronization and offline-first capabilities, now production-ready!API Support Guarantees
General Availability (GA) means API stability! Starting with4.9.0 Ditto will guarantee semver
support of all APIs following industry standards. For more on semver see
semver.org.Changes from the Public Preview
To provide the best product with our GA release we’ve made some final modifications to the underlying architecture that bridges Dart and the Ditto Core for Android. The goal with this change is to provide a higher quality product with improved performance, reliability, and developer experience.These changes provide the following benefits:- Enhanced developer ergonomics through synchronous APIs
- Improved performance for all operations across all platforms
- Reduced complexity improving reliability
- Reduced background operations for better battery life
- Lower memory consumption
Breaking Changes
This release contains a handful of minor syntax changes to provide an improved developer experience and better support the underlying framework. These syntax changes all stem from the ability to support non-async calls across the Dart-Ditto Core FFI.In the initial Dart-Ditto implementation all Dart internal calls were required to make async calls into Ditto. This required us to make all Ditto API methodsasync. Due to the improvements
with our recent changes we are now able to provide synchronous methods. This change will bring a more
natural developer experience.Ditto Initialization Required using await Ditto.init()
From 4.9.0 and later it’s required to call await Ditto.init() before using any Ditto
functionality. Failing to do so can result in incorrect initialization of Ditto and unexpected
failures.Notably, this must happen after WidgetsFlutterBinding.ensureInitialized() has
been called.Flutter’s runApp already calls
WidgetsFlutterBinding.ensureInitialized(), so if calling Ditto.init() inside
the initState of a StatefulWidget, it will just work.To initialize Ditto in main, use the following syntax:Select asnyc functions have become sync
Select functions that don’t require asynchronous execution have been converted from async
to standard sync operations.Changed Methods Include:ditto.startSync();ditto.store.registerObserver(...);ditto.sync.registerSubscription(...);
.then() (often seen in initState()):Methods to setter/getter variables
Async getter/setter method pairs have been converted to properties using Dart’s getter/setter syntax, for a more natural developer experience.Changed Methods Include:| Previous | New |
|---|---|
DittoLogger.setMinimumLogLevel(...) DittoLogger.getMinimumLogLevel(...) | DittoLogger.minimumLogLevel |
DittoLogger.setCustomLogCallback(...) DittoLogger.getCustomLogCallback(...) | DittoLogger.customLogCallback |
Boolean functions renamed from getFoo/setFoo to isFoo
For property types where the value type is bool, the functions will have been renamed
from getFoo and setFoo to isFoo.Changed Methods Include:| Previous | New |
|---|---|
DittoLogger.setEnabled() DittoLogger.getEnabled() | DittoLogger.isEnabled |
ditto.setTransportConfig() ditto.getTransportConfig() | ditto.transportConfig |
Select Async Initialization is now Sync
Objects withasync constructors that didn’t require asynchronous initialization have
been changed for a more natural developer experience.Changed Methods Include:- All
Identitysubclass (E.g.OnlinePlaygroundIdentity)
Restricted Class Modifiers
Many of our types are now eitherfinal classes (which prevent all
subtyping), or interface classes (which allow implements but disallow
other forms of subtyping).If you were previously extending or implementing a type and this is now
disallowed, you can create a wrapper type:Example:Removal of dart:io types in public API
Directory and File are no longer found in our public API.For example Ditto.open() previously took a Directory persistenceDirectory,
but this has been changed to String.This can be resolved by calling .path:Min Kotlin Gradle Plugin Version Upgraded to 1.8.0
Supporting new Android capabilities requires using Kotlin Gradle Plugin version1.8.0 or later.To upgrade:- Navigate to the root folder
- Open
./android/settings.gradle - Update the
org.jetbrains.kotlin.androidplugin to1.8.0
Final Preview ReleaseContains: Reliability and stability improvements.
We’re excited to announce the public preview of the Ditto Flutter SDK!While you can expect major feature compatibility with our production SDKs, we’re continuously refining the experience and closing any minor gaps. Join us on this journey, and share your feedback to help shape the future of Ditto for Flutter!
This change has a large number of new capabilities as well as some minor namings API Breaking Changes. Added: Presence API - Allows receiving syncing information about other peers. See Using Mesh Presence Added: WifiAware as a Transports protocol. Added: Retrieving active subscriptions. Syncing Data > Retrieving Subscriptions Added: Canceling subscriptions. Syncing Data > Canceling Subscriptions Added: Support for sync groups. Creating Sync Groups Added: Support to intercept and reject new connections. Handling Connection Requests Breaking change: AuthenticationStatus.authenticated renamed to isAuthenticated Breaking change: Various TransportConfig-related types have enabled properties renamed to isEnabled Breaking change: HttpListenConfig.interfaceIp renamed to interfaceIP Breaking change: HttpListenConfig.websocketSync renamed to webSocketSync Breaking change: StoreObserver.cancelled renamed to isCancelled
Added: Logger class that provides diagnostics capabilities.
Added: Device Dashboard Support - customers can now see device information on the Ditto Portal.
Added: Support for Attachments. Changed: The default
deviceName will now represent the device’s model. Added: OnlineWithAuthenticationIdentity and ditto.auth Added: User-configurable transport config. Customizing Transports Configurations
Added: Ability to stop sync
ditto.stopSync() Fixed: Cancelling a subscription currently doesn’t trigger any action Fixed: Observer API no longer fires every 50ms. Previously the observer API was using a polling mechanism internally which resulted in an event ever 50ms no matter if there were changes or not. This has been updated with an event listener pattern. Changed: Performance and battery life improvements from observers not continuously firingVersion 4.8.0-beta.6 has been Retracted due to an issue found with Android observer API not firing correctly.Please use earlier or later releases.
The initial beta release of Flutter