Skip to content

Data streams v2 - #1166

Draft
1egoman wants to merge 29 commits into
mainfrom
data-streams-v2
Draft

1egoman wants to merge 29 commits into
mainfrom
data-streams-v2

Conversation

@1egoman

@1egoman 1egoman commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Initial port of data streams v2 to the flutter sdk. This is built on top of #1160, and that PR must be merged first.

Summary

Background context on data streams v2

Previously, the flutter sdk had its own data streams implementation. With data streams v2, the rust implementation will both be quite a bit more stable and gain some new features that make it significantly more performant (single packet data streams and DEFLATE compression when it makes the payload smaller). This roughly doubles data stream throughput in local testing.

In the corresponding swift and android pull requests, I was able to fully cut over to data streams v2. However, the flutter sdk also has to support web, and today uniffi-dart does not support WASM - see here for an early issue on the bindgen side tracking this work.

So in lieu of fully cutting over:

  • All platforms except for web use the rust provided data streams v2 implementation
  • Web keeps the existing pure dart data streams v1 implementation.

Note that it could be possible to make flutter web use the web sdk's data stream v2 implementation, but it looks like it would introduce a lot of infrastructure complexity. Given this and that it seems like flutter web support is somewhat experimental anyway, I'm tempted to keep it on the existing implementation.

New behaviors worth being aware of

All of these are either data streams v2 related changes, or bug fixes.

1. compress option

When sending a data stream, there is a new compress option. Just like how this works on web / rust, this defaults to true. If set to false, then compression will be disabled (useful if you know the data you are sending isn't compressible / you are doing your own compression, which is not uncommon in robotics use cases). The vast majority of users should leave this set to true.

2. Max data stream size

In a rust data streams v2 pull request review comment, we decided that for security reasons it made sense to introduce a maximum data stream size as a DOS protection. This limit is by default 5gb - any data stream that is larger will now read up until that point, and if the stream keeps going, a "payload too large" error will be raised on the stream and exposed to a user on the subsequent .read() call.

If a user is sending a large file, they can override this by setting a new maxPayloadByteLength option on the room.connect call:

await room.connect(
  wsUrl,
  token,
  connectOptions: const ConnectOptions(
    autoSubscribe: true,
    dataStream: const DataStreamOptions(maxPayloadByteLength = 1000),
  ),
);

3. Throwing new data stream errors types

The old flutter specific data streams implementation wasn't quite as strict and didn't surface as many error cases to the caller which were encountered while reading the stream as the rust implementation now does. This needs some testing in some of these edge cases to make sure I didn't inadvertently make this backwards incompatible in a non-aceptable way.


Warning

This pull request was LLM generated and has only been reviewed by a human who isn't a domain expert in android development. I have tested this and confirms it works in the happy path, but no other validation has been done.

A more thorough review of this needs to occur before it could be merged.

Todo

1egoman added 5 commits August 7, 2026 16:30
Groundwork for delivering the Rust core through Dart's Native Assets,
which is only stable from Flutter 3.38 / Dart 3.10 onwards.

The newer language version turns on lints the tree does not yet satisfy:

- `*.g.dart` joins the analyzer exclusions. AGENTS.md already described
  json_serializable output as excluded, but only the protobuf patterns
  actually were; 47 of the 48 new `use_null_aware_elements` hits are in
  generated files nobody edits by hand.
- The remaining `use_null_aware_elements` hit, in `Room`, and four
  `unnecessary_underscores` hits in the RPC tests, are fixed directly.

Crossing Dart 3.7 also switches `dart format` to the tall style, which
reformats the whole tree. That is mechanical and lands separately, in the
commit that follows, so it does not bury this one. `dart format
--set-exit-if-changed` is therefore red at this commit and green again at
the next.

No functional change.
Pure output of `dart format .`. No functional or semantic change.

The formatter picks its style from the package language version, so the
SDK bump in the previous commit crosses Dart 3.7 and switches the whole
tree from the short style to the tall one. `dart format
--set-exit-if-changed` is CI-enforced, so this has to land -- it is split
out only so the bump and its lint fixes stay readable.

Reproduce with `dart format .` on the parent commit.
Establishes the development loop for calling into `livekit-uniffi` from
this SDK, and exercises it with `buildVersion()` -- a synchronous,
argument-free call returning a string, so a green test means the whole
chain is intact: the build hook resolved a cdylib for the target, Native
Assets bundled it, `@Native` bound the symbol, and a value crossed back.

`lib/src/uniffi/` splits native/web with the same conditional-import
pattern as the rest of the SDK. There is no dynamic library to load on
the web, so `uniffi_io.dart` is the only file permitted to import the
generated bindings -- reaching them from anywhere web-reachable pulls
`dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`.
Callers branch on `LiveKitUniffi.isAvailable`. The facade is internal for
now; nothing is added to the public API surface.

`livekit_uniffi` is not on pub.dev, so both pubspecs override it to a
sibling rust-sdks checkout -- overrides do not propagate from a
dependency, hence both. Until it is published this branch cannot merge:
CI has no rust-sdks checkout, so `flutter pub get` will fail there.

Verified: 392 tests pass, web and wasm builds succeed, analyze and format
are clean.
Swaps the native data-stream internals onto `livekit-uniffi`, which
implements data streams v2: single-packet inline sends for small finite
payloads, deflate-raw compression, UTF-8-aware chunking and MTU-bounded
headers. Reimplementing that in Dart would have meant a third copy of a
wire protocol that has to stay byte-compatible with the JS, Swift and
Android SDKs; this way the framing has exactly one implementation.

Mirrors the Swift SDK's `data-streams-v2` branch: one `DataStreams`
subsystem per Room, created eagerly and outliving connect/disconnect so
handler registrations survive a reconnect, with the FFI boundary being
serialized `DataPacket` bytes in both directions. Outbound packets go
back through `Engine.sendDataPacket`, so E2EE wrapping, reliable
sequencing and resume-resend are all unchanged.

Web keeps the existing Dart implementation, moved verbatim behind the
same interface: the core ships a cdylib and cannot run in a browser, and
RPC v2 rides on text streams. Web advertises `clientProtocol` v1 and no
capabilities, so v2 senders fall back to uncompressed multi-packet for
it — interop is safe by spec.

Two findings worth recording, both now in AGENTS.md:

- The core's *push* delegates cannot be used from Dart at all. uniffi
  compiles a callback interface to `Pointer.fromFunction`, valid only on
  the isolate's thread, and the core invokes those from its tokio
  runtime — the VM aborts with "Cannot invoke native callback outside an
  isolate". Both managers are constructed with `delegate: null` and
  drained via the new `nextPackets`/`nextOpenedStream` pull API instead.
  `RemoteParticipantRegistryDelegate` is the one safe callback: it is
  only called inside a `send*` future, which uniffi polls from the
  calling thread.
- Only the pump may dispose a uniffi reader. Disposing from a
  subscription's `onCancel` frees the Rust handle while a `next()` is in
  flight, which surfaces as a SIGBUS with no Dart stack.

Public API is unchanged; `sendBytes`, a `compress` option,
`ClientCapability`, `Participant.capabilities` and
`ClientProtocolVersion.v2` are additive. Protobufs are regenerated —
`DataStream.Header` previously had no `inlineContent`/`compression` and
`ClientInfo.Capability` stopped at `CAP_PACKET_TRAILER`.

Behavior changes, all consequences of the core owning the framing:
`onProgress` loses per-chunk granularity, transport send errors no
longer reach `write()`, `encryptionTypeMismatch` is unreachable,
`ByteStreamReader.readAll()` no longer silently de-duplicates identical
chunks (it collected into a Set), and `sendText`'s `totalLength` is now
the UTF-8 length rather than `codeUnits.length`.
Replaces the bespoke pull methods added to `OutgoingDataStreamManager`
and `IncomingDataStreamManager` with a composed adapter layer, so the
data-stream code itself goes back to exactly what it was.

The managers push their output to a foreign delegate from a tokio
thread, which Dart cannot accept. Rather than teach each manager a
second, pull-shaped mode, `data_stream/polled.rs` implements those same
delegate traits *in Rust*, buffers into a channel, and exposes an
`async fn next_*` the foreign side awaits. The delegate still runs on a
tokio thread — which is fine precisely because it is Rust, so nothing
crosses the FFI until the await resolves.

Three things this buys over the previous shape:

- `incoming.rs` and `outgoing.rs` are untouched, so Swift and Kotlin are
  provably unaffected — not even an `Option` added to a constructor.
- The two halves are wired together inside Rust by
  `polled_{outgoing,incoming}_data_stream_manager`, so no binding has to
  pass a Rust object where `Arc<dyn Trait>` is expected — which
  uniffi-dart cannot currently do anyway.
- The pattern generalizes. Data tracks has the identical
  delegate-on-a-tokio-thread problem and can reuse it.

Not feature-gated for now: the module is small and inert, and gating it
would fork the cdylib build matrix in uniffi-cdylib.yml.

Also closes a lifetime hazard the previous shape shared: the queues now
expose `close()`, which wakes a pending `next_*` with `None` so its pump
can exit and dispose the queue itself. Disposing from `dispose()` while
a pump was blocked would have freed the handle mid-call — the same
use-after-free that showed up as a SIGBUS in the reader path.
`connect` opened with `var roomOptions = this.roomOptions;` while a
parameter of the same name was in scope. Dart permits a local to shadow
a parameter — silently, with no warning and the local winning — so every
`RoomOptions` a caller passed to `connect` was discarded and the Room's
own options were used instead. Nothing surfaced the mismatch.

The parameter is deprecated in favour of the `Room` constructor, but
deprecated is not the same as inert: while it is still accepted it has
to take effect. It now does, falling back to the Room's options when
absent. `Engine.connect` already adopted whatever it was handed, so the
value propagates from there without further changes.

The local is renamed to `effectiveRoomOptions`, since restoring the
parameter's visibility is the whole point and leaving two things called
`roomOptions` in one scope is what caused this.

Adds a regression test, and threads `connectOptions`/`roomOptions`
through the E2E container so it can be exercised. Verified the test
fails against the old shadowing behavior.
The Rust core has always accepted a payload cap — it is the guard against
a sender making a receiver allocate arbitrary memory, including via a
compressed stream that inflates far past its wire size — but nothing
exposed it, so `null` was hardcoded and every room ran with the core's
5 GB default.

Placed on `ConnectOptions` rather than `RoomOptions`, which is where
Swift puts it. It fits the lifecycle better here: the incoming manager is
created lazily on the first inbound packet precisely so a connect-time
value is in effect by the time it is read. Worth knowing it diverges from
Swift if cross-SDK consistency matters more than that.

Also enforced on web, which otherwise would have accepted the option and
silently done nothing with it — the same trap as the ignored
`connect(roomOptions:)` argument. The Dart path tracks accumulated
content bytes per stream so an unknown-length stream is capped too, not
just one that declares an oversized `totalLength`.

Both paths follow the core's semantics, which are subtler than they look:
the stream-opened event fires *before* the cap is applied, so the topic
handler still runs and it is the reader that fails with
`LengthExceeded`. A consumer is told the stream died rather than watching
it never arrive. My first pass had web refusing the stream outright and
the doc comment describing that; both are corrected here.
hiroshihorie pushed a commit that referenced this pull request Aug 11, 2026
… variable, NOT implicitly this.roomOptions (#1169)

While working on #1166, I discovered this bug incidentally, so here is
an isolated fix.

`connect`'s first line is `var roomOptions = this.roomOptions;`.
However, a parameter of the same name (`roomOptions`) was in scope.
After some unexpected behavior, I realized that dart permits a local to
shadow a parameter (silently, with no warning and the local winning) so
every `RoomOptions` a caller passed to `connect` was discarded and the
Room's own options were used instead. Nothing surfaced the mismatch.

The `roomOptions` parameter on `connect` seems to be deprecated in favor
of the parameter on the `Room` constructor, but deprecated is not the
same as inert: while it is still accepted it has to take effect. It now
does, falling back to the Room's options when absent. `Engine.connect`
already adopted whatever it was handed, so the value propagates from
there without further changes.

The local is renamed to `effectiveRoomOptions`, since restoring the
parameter's visibility is the whole point and leaving two things called
`roomOptions` in one scope is what caused this.

I also addeds a regression test, and threaded
`connectOptions`/`roomOptions` through the E2E container so it can be
exercised. I verified the test failed against the old shadowing
behavior.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
hiroshihorie and others added 17 commits August 11, 2026 19:54
# Conflicts:
#	example/pubspec.yaml
#	lib/src/core/engine.dart
#	lib/src/core/room.dart
#	lib/src/e2ee/key_provider.dart
#	lib/src/extensions.dart
#	lib/src/json/agent_attributes.g.dart
#	lib/src/token_source/caching.g.dart
#	lib/src/token_source/jwt.g.dart
#	lib/src/token_source/room_configuration.g.dart
#	lib/src/token_source/token_source.g.dart
#	pubspec.lock
#	pubspec.yaml
… core

handleIncomingPacket received the encryption type from the engine and dropped
it. The core now requires it — it cannot be recovered from the bytes, since
decryption replaces the encrypted_packet oneof member — and uses it to hold
every stream to the encryption its header arrived under, failing mismatched
chunks and trailers with EncryptionTypeMismatch (whose expected/received
detail is surfaced in the error message).

Incoming stream infos are now stamped with the encryption the stream actually
arrived under, as reported by the core, instead of the room's own setting — a
plaintext stream is reported as plaintext even in an encrypted room. Outgoing
infos keep the room-derived value: payload crypto happens in the engine after
the core.
The incoming pull adapter grew a second channel: nextClosedStream() yields a
notification once per opened stream (trailer, inline completion, failure, or
abort). Nothing consumes the signal yet — it exists for ordered per-topic
delivery, which this SDK doesn't implement — but the channel is unbounded on
the Rust side, so leaving it undrained would grow memory with every stream
received for the manager's lifetime. A discard pump drains it.

The two pumps share one queue object, so disposal moves out of the incoming
pump: the queue is disposed exactly once, after both pumps have exited
(close() wakes them both). Disposing from either pump's own exit path would
free the handle while the other might still have a call in flight.
The incoming manager's payload cap is fixed at its construction, and the
ConnectOptions.dataStream it comes from can change between connects of the
same Room. reset() only aborted open streams and reused the manager, silently
pinning the first session's cap — exactly the hazard the core's constructor
docs call out.

reset() now discards the manager: abort open streams so blocked readers error,
close the queue so both pumps wake and dispose it, and release the manager.
The next inbound packet lazily builds a fresh one against the current connect
options; handler registrations live on this class and survive.
- The uniffi smoke suite now drives the polled incoming manager end to end:
  2-arg handlePacketReceived, the in-order openStreamCount query, and the
  stream-closed queue. It is the gate that fails first when the vendored
  bindings fall behind the Rust crate.
- v2 tests: a chunk that changes encryption fails its reader with
  EncryptionTypeMismatch (with the expected/received detail), stream info
  reports the arrival encryption rather than the room's setting, and open
  stream accounting is observable (including that reset() discards the
  manager).
- debugOpenStreamCount on NativeDataStreams: answered on the core's loop in
  order with previously fed packets, so tests wait deterministically instead
  of polling.
livekit_uniffi 0.1.10 is published, and its release carries the prebuilt
libraries the build hook downloads, so the path overrides to a sibling
rust-sdks checkout are no longer needed in either pubspec.
The path override becomes the opt-in for developing against unreleased
crate changes rather than the default, and the note about releases
lacking assets is replaced with how download mode behaves.
flutter_webrtc moved to 1.6.2+hotfix.1 on main.
0.1.12 is the first version published by the release pipeline. Its build
hook keeps each target architecture's downloaded library in its own
directory, which the universal macOS release build needs; 0.1.10 wrote
both to one path and the macOS CI job failed in lipo.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The example logs the Rust core build version at startup and shows it on
the connect page, one synchronous FFI call that proves the native
library was bundled and loads on the platform.
The change adds a public API and a dependency whose build hook downloads
native libraries during consumer builds, which is a feature release
rather than a patch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The automatic merge of pubspec.lock dropped the livekit_uniffi, archive
and posix entries that only this branch resolves. Regenerated with
flutter pub get.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
reliability: Reliability.reliable,
);
} catch (e) {
// The core acknowledges sends unconditionally, so there is nobody to propagate this to.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This silently swallows send failures. I believe the prior version exposed failures to the caller.

/// The pump owns the queue's lifetime and is the only thing that may dispose it — freeing it
/// while a `nextPackets` is in flight is a use-after-free. [dispose] wakes us by closing the
/// queue rather than releasing it.
Future<void> _pumpOutgoing() async {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this waitForBufferStatusLow?

Base automatically changed from uniffi-rust-core to main October 19, 2026 12:35
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Caution

Breaking change detected without major changeset

dart-apitool detected the following breaking changes:

Preparing git repository: https://github.com/livekit/client-sdk-flutter
Using ref: main
Cloning git repository: https://github.com/livekit/client-sdk-flutter
Checking out ref: main
Successfully cloned to: /tmp/UOGBEE
Preparing package dependencies for git package https://github.com/livekit/client-sdk-flutter (forced Flutter)
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 100.0.0 (109.0.0 available)
  analyzer 13.0.0 (14.5.0 available)
  archive 4.3.0 (4.5.2 available)
  build 4.0.7 (5.0.0 available)
  build_config 1.3.2 (1.4.0 available)
  build_daemon 4.1.5 (4.1.7 available)
  build_runner 2.15.1 (2.17.1 available)
  built_collection 5.1.1 (5.1.2 available)
  built_value 8.12.7 (8.13.0 available)
  clock 1.1.2 (1.1.3 available)
  code_assets 1.2.1 (2.1.0 available)
  code_builder 4.11.1 (4.13.0 available)
  connectivity_plus 7.3.1 (7.3.2 available)
  dart_style 3.1.9 (3.1.14 available)
  dart_webrtc 1.8.1 (1.8.2 available)
  dbus 0.7.14 (0.8.0 available)
  device_info_plus 13.2.0 (13.3.0 available)
  glob 2.1.3 (2.2.0 available)
  hooks 2.0.2 (2.2.0 available)
  io 1.0.5 (1.1.0 available)
  jni 1.0.3 (1.1.0 available)
  jni_flutter 1.0.2 (1.0.4+1 available)
  logger 2.7.0 (2.8.0 available)
  material_color_utilities 0.13.0 (0.13.1 available)
  mime 2.0.0 (2.1.0 available)
  mockito 5.7.0 (5.8.1 available)
  nm 0.5.0 (0.6.0 available)
  objective_c 9.5.0 (9.6.2 available)
  package_config 2.2.0 (3.0.0 available)
  petitparser 7.0.2 (7.1.0 available)
  platform 3.1.6 (3.2.0 available)
  pool 1.5.2 (1.5.3 available)
  protobuf 6.0.0 (6.1.0 available)
  pub_semver 2.2.0 (2.2.1 available)
  pubspec_parse 1.5.0 (1.6.0 available)
  record_use 0.6.0 (1.1.1 available)
  sdp_transform 0.3.2 (0.4.0 available)
  shelf 1.4.2 (1.4.3 available)
  source_gen 4.2.4 (4.3.1 available)
  stack_trace 1.12.1 (1.12.2 available)
  stream_transform 2.1.1 (2.1.2 available)
  synchronized 3.4.1+1 (3.5.0 available)
  test_api 0.7.12 (0.7.15 available)
  vector_math 2.4.2 (2.4.3 available)
  vm_service 15.2.0 (15.4.0 available)
  xml 6.6.1 (7.1.0 available)
  yaml 3.1.3 (3.1.4 available)
Got dependencies!
47 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Resolving dependencies in `./example`...
Downloading packages...
Got dependencies in `./example`.
Preparing . (forced Flutter)
Copying sources from .
Preparing package dependencies for local package . (forced Flutter)
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 100.0.0 (109.0.0 available)
  analyzer 13.0.0 (14.5.0 available)
  archive 4.3.0 (4.5.2 available)
  build 4.0.7 (5.0.0 available)
  build_config 1.3.2 (1.4.0 available)
  build_daemon 4.1.5 (4.1.7 available)
  build_runner 2.15.1 (2.17.1 available)
  built_collection 5.1.1 (5.1.2 available)
  built_value 8.12.7 (8.13.0 available)
  clock 1.1.2 (1.1.3 available)
  code_assets 1.2.1 (2.1.0 available)
  code_builder 4.11.1 (4.13.0 available)
  connectivity_plus 7.3.1 (7.3.2 available)
  dart_style 3.1.9 (3.1.14 available)
  dart_webrtc 1.8.1 (1.8.2 available)
  dbus 0.7.14 (0.8.0 available)
  device_info_plus 13.2.0 (13.3.0 available)
  glob 2.1.3 (2.2.0 available)
  hooks 2.0.2 (2.2.0 available)
  io 1.0.5 (1.1.0 available)
  jni 1.0.3 (1.1.0 available)
  jni_flutter 1.0.2 (1.0.4+1 available)
  logger 2.7.0 (2.8.0 available)
  material_color_utilities 0.13.0 (0.13.1 available)
  mime 2.0.0 (2.1.0 available)
  mockito 5.7.0 (5.8.1 available)
  nm 0.5.0 (0.6.0 available)
  objective_c 9.5.0 (9.6.2 available)
  package_config 2.2.0 (3.0.0 available)
  petitparser 7.0.2 (7.1.0 available)
  platform 3.1.6 (3.2.0 available)
  pool 1.5.2 (1.5.3 available)
  protobuf 6.0.0 (6.1.0 available)
  pub_semver 2.2.0 (2.2.1 available)
  pubspec_parse 1.5.0 (1.6.0 available)
  record_use 0.6.0 (1.1.1 available)
  sdp_transform 0.3.2 (0.4.0 available)
  shelf 1.4.2 (1.4.3 available)
  source_gen 4.2.4 (4.3.1 available)
  stack_trace 1.12.1 (1.12.2 available)
  stream_transform 2.1.1 (2.1.2 available)
  synchronized 3.4.1+1 (3.5.0 available)
  test_api 0.7.12 (0.7.15 available)
  vector_math 2.4.2 (2.4.3 available)
  vm_service 15.2.0 (15.4.0 available)
  xml 6.6.1 (7.1.0 available)
  yaml 3.1.3 (3.1.4 available)
Got dependencies!
47 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Resolving dependencies in `./example`...
Downloading packages...
Got dependencies in `./example`.
Omitting pub get (package config already present)
Analyzing /tmp/UOGBEE
Omitting pub get (package config already present)
Analyzing .
Cleaning up
Cleaning up
Checking Package version
ignoring prerelease
-- Generating report using: Console Reporter --
BREAKING CHANGES
└─┬ Class Participant
  └── Field "capabilities" added (required) (CF02)
Non-Breaking changes
├── Interface "DataStreamOptions" added (CI02) (minor)
├── Interface "ClientCapability" added (CI02) (minor)
├── Interface "DataStreams" added (CI02) (minor)
├── Interface "SendBytesOptions" added (CI02) (minor)
├── Field "kDefaultMaxPayloadByteLength" added (CF02) (minor)
├─┬ Class Room
│ └── Field "dataStreams" added (CF02) (minor)
├─┬ Class ConnectOptions
│ ├── Field "dataStream" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "dataStream" added (CE02) (minor)
├─┬ Class ClientProtocolVersion
│ └── Field "v2" added (CF02) (minor)
├─┬ Class RemoteParticipant
│ └── Field "capabilities" added (CF02) (minor)
├─┬ Class LocalParticipant
│ └── Field "capabilities" added (CF02) (minor)
├─┬ Class DataStreamError
│ └── New entry point: livekit_client.dart (CP01) (minor)
├─┬ Class DataStreamErrorReason
│ └── New entry point: livekit_client.dart (CP01) (minor)
├─┬ Class DataStreamParticipantMethods
│ └── Method "sendBytes" added (CE11) (minor)
└─┬ Class SendTextOptions
  ├── Field "compress" added (CF02) (minor)
  └─┬ Constructor new
    └── Parameter "compress" added (CE02) (minor)
To learn more about the detected changes visit: https://github.com/bmw-tech/dart_apitool/blob/main/readme/change_codes.md
Version Check
New Version is too low!

Old version: "2.13.1"
New version: "2.13.1"
Needed version: "3.0.0"

Got "2.13.1" expected >= "3.0.0" (breaking changes)

If this is intentional, please add a changeset with major level in .changes/:

major type="changed" "Description of breaking change"

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants