Skip to content

Observe the path configuration loading state#195

Merged
jayohms merged 25 commits into
mainfrom
observe-path-config
Mar 27, 2026
Merged

Observe the path configuration loading state#195
jayohms merged 25 commits into
mainfrom
observe-path-config

Conversation

@jayohms

@jayohms jayohms commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

This introduces a StateFlow-based loading mechanism for path configuration so apps can observe when the configuration loads and from which source.

Key Changes

PathConfigurationData — New class containing only the serializable configuration data (rules, settings). Extracted from PathConfiguration so the StateFlow emits lightweight data objects rather than the full PathConfiguration instance. Implements equals()/hashCode() so StateFlow properly deduplicates identical emissions.

PathConfigurationLoadState — New sealed class hierarchy: Idle for the initial state, and Loaded with three subclasses (BundledAssetLoaded, CachedRemoteLoaded, RemoteLoaded). Apps can check is Loaded for any successful load, or match on the specific subclass when the source matters.

PathConfigurationLoader — Refactored to return load states directly. Smarter loading order: prefers the cached remote config over the bundled asset. Falls back to bundled only when no cache exists or the cache fails to parse. Remote fetch runs on Dispatchers.IO.

PathConfiguration — Exposes loadState: StateFlow<PathConfigurationLoadState> for app observation. The bundled/cached config loads synchronously (to maintain backwards compatibility) in load() so it's available immediately. The remote fetch runs asynchronously on IO. All state mutations are synchronized for thread safety between the IO loading scope and main-thread reads. If load() is called multiple times, the previous job is cancelled before fetching the configuration again.

Example Usage

// Observe all configuration updates
lifecycleScope.launch {
    Hotwire.config.pathConfiguration.loadState.collect { state ->
        when (state) {
            is PathConfigurationLoadState.NotLoaded -> {
                // Not loaded yet
            }
            is PathConfigurationLoadState.Loaded -> {
                // Configuration available — check settings, update UI, etc.
                val settings = state.configuration.settings
                val properties = state.configuration.properties("https://example.com/home")
            }
        }
    }
}
// Distinguish the source when needed
lifecycleScope.launch {
    Hotwire.config.pathConfiguration.loadState.collect { state ->
        when (state) {
            is PathConfigurationLoadState.NotLoaded -> {}
            is PathConfigurationLoadState.Loaded.BundledAssetLoaded -> {
                // First load from bundled asset (fresh install, no cache)
            }
            is PathConfigurationLoadState.Loaded.CachedRemoteLoaded -> {
                // Loaded from previously cached remote config
            }
            is PathConfigurationLoadState.Loaded.RemoteLoaded -> {
                // Fresh config from the server
            }
        }
    }
}
// One-shot: wait for the first available config
lifecycleScope.launch {
    val loaded = Hotwire.config.pathConfiguration.loadState
        .first { it is PathConfigurationLoadState.Loaded }
    // Configuration is ready
}

Comment thread core/src/main/kotlin/dev/hotwire/core/turbo/config/PathConfigurationLoadState.kt Outdated
Comment thread core/src/main/kotlin/dev/hotwire/core/turbo/config/PathConfigurationLoadState.kt Outdated
Comment thread core/src/main/kotlin/dev/hotwire/core/turbo/config/PathConfigurationLoadState.kt Outdated
Comment thread core/src/main/kotlin/dev/hotwire/core/turbo/config/PathConfigurationData.kt Outdated
Comment thread core/src/main/kotlin/dev/hotwire/core/turbo/config/PathConfiguration.kt Outdated
Comment thread core/src/main/kotlin/dev/hotwire/core/turbo/config/PathConfiguration.kt Outdated
Comment thread core/src/main/kotlin/dev/hotwire/core/turbo/config/PathConfigurationData.kt Outdated
@jayohms jayohms merged commit 167c04b into main Mar 27, 2026
1 check passed
@jayohms jayohms deleted the observe-path-config branch March 27, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants