DQL Strict Mode
DQL_STRICT_MODE=false
), Ditto is more flexible and will infer the CRDT type based on the document’s shape:Differ
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.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 |
->
) are deprecated. Read more.DELETE
to remove documents.DQL_STRICT_MODE
as a system parameter to opt-out of requiring collection definitions (#16573)network_use_nextgen_multihop_stack
(#16370)DittoDiff
class to represent diffs produced by the DittoDiffer
DittoDiffer
class for calculating diffs between query resultstransaction()
method on DittoStore
for performing DQL transactionsDittoTransaction
class to represent an active DQL transactionDittoTransactionInfo
class for transaction informationDittoTransactionCompletionAction
for commit/rollback actionsisStopped
property of AttachmentFetcher
instances now becomes true
after completing an attachment fetchQueryResult
and QueryResultItem
ditto.store.newAttachment
now returns a Future<Attachment>
rather than an Attachmentditto.close()
now returns a Future<void>
rather than void
4.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:DittoLogger.isEnabled = false
immediately after calling await Ditto.init()
.4.10.0-experimental-hot-restart.0
.Ditto.init()
(#15880)stopSync()
is called (#SDKS-707)onChange
parameter
or the StoreObserver.changes
stream)await 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
Ditto will guarantee semver
support of all APIs following industry standards. For more on semver see
semver.org.async
. 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.await Ditto.init()
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:asnyc
functions have become syncasync
to standard sync operations.Changed Methods Include:ditto.startSync();
ditto.store.registerObserver(...);
ditto.sync.registerSubscription(...);
.then()
(often seen in initState()
):Previous | New |
---|---|
DittoLogger.setMinimumLogLevel(...) DittoLogger.getMinimumLogLevel(...) | DittoLogger.minimumLogLevel |
DittoLogger.setCustomLogCallback(...) DittoLogger.getCustomLogCallback(...) | DittoLogger.customLogCallback |
getFoo
/setFoo
to isFoo
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 |
async
constructors that didn’t require asynchronous initialization have
been changed for a more natural developer experience.Changed Methods Include:Identity
subclass (E.g. OnlinePlaygroundIdentity
)final
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:dart:io
types in public APIDirectory
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
:1.8.0
or later.To upgrade:./android/settings.gradle
org.jetbrains.kotlin.android
plugin to 1.8.0
deviceName
will now represent the device’s model.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 firing