Release v2.1.0 - Compose Integration, Persistent Dispatch & Test Hardening#2
Merged
vietnguyentuan2019 merged 5 commits intomainfrom Mar 16, 2026
Merged
Release v2.1.0 - Compose Integration, Persistent Dispatch & Test Hardening#2vietnguyentuan2019 merged 5 commits intomainfrom
vietnguyentuan2019 merged 5 commits intomainfrom
Conversation
added 5 commits
March 16, 2026 09:53
Priority 1 - Critical fixes: - Add dispatchWithPriority() on KRelayInstance - fixes API inconsistency where priority dispatch existed only on the singleton, not on instances - Fix Metrics.enabled flag: record*() methods now correctly no-op when metrics are disabled (was always recording regardless of flag) - Add duplicate registration warning in debug mode - logs when register<T>() overwrites an existing alive implementation - Fix iOS MainThreadExecutor comment: remove misleading "99% accurate" note, NSThread.isMainThread is the correct and reliable check - Add CI/CD via GitHub Actions (.github/workflows/ci.yml) - NOTE: requires removing .github from .gitignore to enable tracking - Add docs/LIFECYCLE.md: comprehensive Android/iOS lifecycle integration guide with Activity, Fragment, Compose, UIViewController, SwiftUI examples - Update CHANGELOG.md with [Unreleased] v2.1.0 entry Priority 2 - Important: - Add Dokka 1.9.20 for API doc generation (./gradlew :krelay:dokkaHtml) - Add version compatibility matrix to README (KRelay vs Kotlin/KMP/AGP/platforms) - Add KRelayFlowAdapter.kt sample documenting KRelay + coroutines/Flow patterns and when to use KRelay vs Flow directly - Add KRelayInstancePriorityTest: 6 tests verifying dispatchWithPriority on instances works correctly (queue, immediate, replay, isolation) - Update MetricsTest and MetricsIntegrationTest to opt-in enabled=true
…Guides Priority 3 features: - Persistent Dispatch: dispatchPersisted<T>() survives process death via named actions + ActionFactory pattern (KRelayPersistence.kt, PersistedDispatch.kt). Includes SharedPreferencesPersistenceAdapter (Android) and NSUserDefaultsPersistenceAdapter (iOS). PersistedCommand uses length-prefix serialization to handle all special characters. - Compose Multiplatform: KRelayEffect<T> composable and rememberKRelayImpl<T> helper (KRelayCompose.kt) for lifecycle-safe registration via DisposableEffect. - Integration guides: COMPOSE_INTEGRATION.md and SWIFTUI_INTEGRATION.md covering idiomatic patterns for both platforms. - Test isolation fix in PersistedDispatchTest to prevent state pollution across the full JUnit test suite (all 161 tests pass).
New in v2.1.0 stability pass:
- scopeToken field on QueuedAction (optional, null = untagged)
- dispatch<T>(scopeToken, block) — tags queued action with caller identity
- cancelScope(token) on KRelayInstance + KRelay singleton — removes only
actions tagged with the given token across all feature queues
- scopedToken() utility generates a unique, human-readable token per call
- All APIs are purely additive; existing code unchanged
Use in ViewModel to auto-clean lambda captures:
private val token = scopedToken()
relay.dispatch<ToastFeature>(token) { it.show("Done") }
override fun onCleared() = relay.cancelScope(token)
Also fix DiagnosticDemo test isolation: add @BeforeTest/@AfterTest to
restore KRelay.actionExpiryMs and maxQueueSize to defaults after each
demo test, preventing config leak that caused intermittent failures in
MultiFeatureCoordinationDemo when test execution order placed
DiagnosticDemo.demoScenario6 (actionExpiryMs=0) before it.
171 tests, 0 failures.
…ening ## Core Library (krelay/) - Add KRelay.instance public property for cross-module access - Add dispatchWithPriority on KRelayInstance (was singleton-only) - Add Scope Token API: scopedToken(), cancelScope(token), dispatch(token, block) - Add resetConfiguration() on KRelayInstance and KRelay - Add dispatchPersisted + KRelayPersistenceAdapter (SharedPreferences/NSUserDefaults) - Add enqueueActionUnderLock() helper — eliminates ~50 lines of duplicated logic - Fix KRelayMetrics wiring (recordDispatch/Queue/Replay now actually fire) - Fix KRelayMetrics.enabled flag (was always recording regardless of flag) - Fix iOS KClass bridging (register/dispatch now find correct interface key) - Fix duplicate registration debug log ## Compose Integration (composeApp/) - Add KRelayEffect<T> composable (auto-unregisters on dispose) - Add rememberKRelayImpl<T> composable (register + return impl) - Fix KRelayCompose.kt: KRelay.defaultInstance -> KRelay.instance (cross-module) - Fix Voyager demo: upgrade to 1.1.0-beta03, DisposableEffect + rememberCoroutineScope - Fix Android 15+ 16KB page alignment (android.allow_non_16k_pages) ## Testing - Add 11 new test files: integration, stress, system, unit, instrumented - Rewrite LockStressTest and ScopeTokenConcurrentStressTest for iOS GCD safety - Fix EnqueueBehaviorIntegrationTest expiry timing (delay(5) + actionExpiryMs=0L) - Fix SharedPreferencesPersistenceAdapterTest: JUnit4 arg order, scope name, waitForIdleSync - Add CI/CD pipeline (.github/workflows/ci.yml) ## Maven Publishing - Add emptyJavadocJar to all publications (Maven Central requirement) - Update POM description to user-facing language - Version: 2.1.0 ## Documentation - Rewrite README with pain-first messaging and integration table - Update CHANGELOG.md: finalize [2.1.0] - 2026-03-16 - Add RELEASE_NOTES_2.1.0.md - Update QUICK_REFERENCE.md, COMPOSE_INTEGRATION.md, ROADMAP.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
KRelayEffect<T>andrememberKRelayImpl<T>built-in composables with auto-unregister on dispose;KRelay.instancepublic property for cross-module accessscopedToken()/cancelScope(token)for fine-grained queue cleanup per ViewModeldispatchPersisted<T>()+SharedPreferencesPersistenceAdapter(Android) +NSUserDefaultsPersistenceAdapter(iOS)emptyJavadocJaradded to all publications (Maven Central compliance)Test plan
./gradlew :krelay:testDebugUnitTest— 237 tests, all pass (JVM)./gradlew :krelay:iosSimulatorArm64Test— 237 tests, all pass (iOS Simulator)./gradlew :krelay:connectedDebugAndroidTest— 19 tests, all pass (Pixel 6 Pro, Android 16)./gradlew :composeApp:compileDebugKotlinAndroid— builds clean