3.0.0¶
Changes are based on the published 2.3.0 tag.
Breaking changes and migration¶
- The Compose builder,
AnimationConfig,outsideComposableand related extensions are removed.ObserveComposableWrapperis replaced by the markedDataResultContentScopeDSL. Render snapshots withDataResultContent(result)orresult.Content; collect aFlow<DataResult<T>>withComposableDataResult(flow)orflow.Content. - Animations are disabled by default. Supply an
AnimatedContenttransitionSpecwhen needed. Manage side effects explicitly withLaunchedEffect; 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. UsesetorsetAsync, 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.
selectAsyncpublishes and compares outputs on the worker. Synchronous setters, restore and cheapselectremain 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-onlychecks 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 SDKtoolspackage. - 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.