Skip to content

3.0.0

Changes are based on the published 2.3.0 tag.

Breaking changes and migration

  • The Compose builder, AnimationConfig, outsideComposable and related extensions are removed. ObserveComposableWrapper is replaced by the marked DataResultContentScope DSL. Render snapshots with DataResultContent(result) or result.Content; collect a Flow<DataResult<T>> with ComposableDataResult(flow) or flow.Content.
  • Animations are disabled by default. Supply an AnimatedContent transitionSpec when needed. Manage side effects explicitly with LaunchedEffect; convert LiveData to Flow before collection. See the Compose migration guide.
  • State holders privately own their SavedStateHandle keys. Direct handle[key] writes and raw handle flows no longer update an active holder. Use set or setAsync, with one active holder per key. Existing keys, JSON strings, serializers and defaults remain readable without conversion. See State migration.

Compose rendering and typed observers

  • Add stateless rendering and lifecycle-aware Flow collection; pass a null lifecycle owner to collect for the composition's lifetime without lifecycle gating.
  • Keep structural animation identity across payload updates. Cache visible observers per snapshot and registration list, preserving registration identity when earlier observers become hidden. Render every matching observer. Sequence animation keys do not consume their source.
  • Add KClass/reified typed error observers and DataResult helpers with distinct JVM names. Typed and untyped handlers are additive. Exception recovery requires a handler matching both the thrown exception and the replayed result's data filter; unmatched failures remain visible.
  • Remove unused Compose AtomicFU configuration and the unused animation import.

State snapshots and worker execution

  • Publish payload and transient result status from one immutable snapshot. Save prepared JSON before notifying collectors, including reentrant replacements, clears and cancellation.
  • Prepare detached payloads, serialization and deep equality on the worker dispatcher for async APIs; commit on the owner scope and reject obsolete work. Recompare on the worker if the owner changes during preparation. Equal payloads retain their previous immutable value.
  • Retain the last payload during loading, errors and completion. Restore non-null payloads as Success and null as None; preserve explicit nulls and initialization of absent entries.
  • Share expensive projections with native coroutine operators. selectAsync publishes and compares outputs on the worker. Synchronous setters, restore and cheap select remain caller-thread APIs.
  • Add opt-in Android app/Macrobenchmark modules comparing a frozen baseline with the new code at 100, 1,000 and 10,000 records. These modules are excluded from ordinary CI coverage/publication.

CI and publication

  • Align publication/recovery with Arch Lumber and Arch Android. Create the GitHub Release after both publication tasks succeed, without HTTP polling for public Maven availability/indexing. Retain Central DeploymentValidation.VALIDATED, exact annotated-tag provenance and master CI gates.
  • Verify every omitted destination during manual recovery; release-only checks both registries. Use this versioned changelog for GitHub Release notes, with generated notes only as a fallback.
  • Keep required CodeQL scans for Actions, Kotlin and Python, using project Kotlin 2.4.20 directly. Add separate weekly/manual scans with explicit JVM/Android compilation and separate categories.
  • Make aggregate Detekt analyze production files across every KMP source set.
  • Share generated Android class exclusions across module/root Kover reports and verification. Disable Codecov discovery so only the root XML report is uploaded. Keep existing coverage floors.
  • Update Android SDK setup to v4 and the GitHub App token action to v3. Use maintained command-line tools and platform-tools, without the obsolete SDK tools package.
  • Keep the versioned JavaScript Yarn lockfile and verify Gradle with its official SHA-256 checksum.

Dependency updates from 2.3.0

Component Before After
Kotlin 2.4.10 2.4.20
Gradle 9.7.1 9.8.0
AGP 9.4.0 9.4.1
Compose / Android Compose test manifest 1.12.0 1.12.1
Kover 0.9.9 0.9.11
JaCoCo 0.8.14 0.8.15
Robolectric 4.16.1 4.17
MkDocs Material 9.7.6 9.7.7
Android compile SDK 37 37.2

Kover 0.9.11 reverts the 0.9.10 configuration-cache coverage regression. Android minSdk stays 23, Build Tools stay 37.0.0 and existing KMP targets remain unchanged. Library modules do not define an app targetSdk; opt-in benchmark apps use API 37. The dependency audit also covers plugins, Actions and the optional UI Automator 2.4.0 update, deferred pending device validation.

Validation and practical limits

Local validation on 2026-10-01 passed:

  • ciBuild ciCoverage, ciLint, ciDocs, root/module coverage verification and strict MkDocs.
  • JVM/Android host reports: 1,581 passed, 6 skipped, zero failures/errors.
  • JS/Wasm browser reports: 226 passed, zero failures/errors.
  • 25 policy/recovery tests, actionlint and Markdown formatting.
  • State coverage: 97.49% lines, 97.56% instructions and 83.87% branches.

The earlier six-case Android emulator run validated rotation and background-process restoration, one iteration per case. It does not establish hardware frame-time acceptance. Apple tests and framework linking require the macOS CI run for this release's exact head. Physical-device frame measurements remain pending; no Android frame envelope is claimed. See performance limits. On JS/Wasm a dispatcher does not create a background thread; expensive work must cooperate with the event loop or use an application-provided worker. SavedStateHandle size limits still apply.