CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-runtime--runtime-desktop

Tree composition support and runtime infrastructure for Compose Multiplatform desktop applications with declarative UI development APIs.

Pending
Overview
Eval results
Files

collections.mddocs/

Collections and Observables

Reactive collections and observable data structures that integrate with the Compose runtime system. These collections automatically trigger recomposition when their contents change.

Capabilities

State Lists

Mutable lists that trigger recomposition when modified.

/**
 * Creates a mutable list that triggers recomposition when changed
 * @param elements Initial elements for the list
 * @return SnapshotStateList instance
 */
fun <T> mutableStateListOf(vararg elements: T): SnapshotStateList<T>

/**
 * Mutable list implementation that integrates with Compose state system
 * Modifications to this list will trigger recomposition of observing composables
 */
interface SnapshotStateList<T> : MutableList<T> {
    /**
     * Adds all elements from the specified collection
     * @param elements Collection of elements to add
     * @return true if list was modified
     */
    fun addAll(elements: Collection<T>): Boolean
    
    /**
     * Removes all elements that match the predicate
     * @param predicate Function to test elements
     * @return true if any elements were removed
     */
    fun removeAll(predicate: (T) -> Boolean): Boolean
}

Usage Examples:

import androidx.compose.runtime.*

@Composable
fun StateListExample() {
    val items = remember { mutableStateListOf("Apple", "Banana", "Cherry") }
    
    Column {
        // Display list items - recomposes when list changes
        items.forEach { item ->
            Text("• $item")
        }
        
        Row {
            Button(onClick = { items.add("Orange") }) {
                Text("Add Orange")
            }
            
            Button(onClick = { items.removeAt(0) }) {
                Text("Remove First")
            }
        }
    }
}

@Composable
fun TodoListExample() {
    val todos = remember { mutableStateListOf<Todo>() }
    var newTodoText by remember { mutableStateOf("") }
    
    Column {
        LazyColumn {
            items(todos) { todo ->
                TodoItem(
                    todo = todo,
                    onToggle = { 
                        val index = todos.indexOf(todo)
                        todos[index] = todo.copy(completed = !todo.completed)
                    },
                    onDelete = { todos.remove(todo) }
                )
            }
        }
        
        Row {
            TextField(
                value = newTodoText,
                onValueChange = { newTodoText = it }
            )
            Button(
                onClick = {
                    if (newTodoText.isNotEmpty()) {
                        todos.add(Todo(text = newTodoText, completed = false))
                        newTodoText = ""
                    }
                }
            ) {
                Text("Add")
            }
        }
    }
}

State Maps

Mutable maps that trigger recomposition when modified.

/**
 * Creates a mutable map that triggers recomposition when changed
 * @param pairs Initial key-value pairs for the map
 * @return SnapshotStateMap instance
 */
fun <K, V> mutableStateMapOf(vararg pairs: Pair<K, V>): SnapshotStateMap<K, V>

/**
 * Mutable map implementation that integrates with Compose state system
 * Modifications to this map will trigger recomposition of observing composables
 */
interface SnapshotStateMap<K, V> : MutableMap<K, V> {
    /**
     * Puts all key-value pairs from the specified map
     * @param from Map containing pairs to add
     */
    fun putAll(from: Map<out K, V>)
    
    /**
     * Removes entries that match the predicate
     * @param predicate Function to test entries
     * @return true if any entries were removed
     */
    fun removeAll(predicate: (Map.Entry<K, V>) -> Boolean): Boolean
}

Usage Examples:

@Composable
fun StateMapExample() {
    val userScores = remember { 
        mutableStateMapOf(
            "Alice" to 100,
            "Bob" to 85,
            "Charlie" to 92
        )
    }
    
    Column {
        Text("Leaderboard")
        
        // Display scores - recomposes when map changes
        userScores.entries.sortedByDescending { it.value }.forEach { (name, score) ->
            Text("$name: $score points")
        }
        
        Row {
            Button(onClick = { userScores["Alice"] = (userScores["Alice"] ?: 0) + 10 }) {
                Text("Boost Alice")
            }
            
            Button(onClick = { userScores["David"] = 75 }) {
                Text("Add David")
            }
        }
        
        Text("Total players: ${userScores.size}")
    }
}

@Composable
fun ConfigurationExample() {
    val settings = remember {
        mutableStateMapOf(
            "darkMode" to false,
            "notifications" to true,
            "autoSave" to true
        )
    }
    
    Column {
        settings.entries.forEach { (key, value) ->
            Row {
                Switch(
                    checked = value as Boolean,
                    onCheckedChange = { settings[key] = it }
                )
                Text(key)
            }
        }
        
        Button(
            onClick = { 
                settings.clear()
                // Reset to defaults
                settings.putAll(mapOf(
                    "darkMode" to false,
                    "notifications" to true,
                    "autoSave" to true
                ))
            }
        ) {
            Text("Reset Settings")
        }
    }
}

Flow Integration

Convert reactive streams to Compose State.

/**
 * Collects values from a Flow and represents them as State
 * @param initial Initial value to use before first emission
 * @param context CoroutineContext for collection (default: EmptyCoroutineContext)
 * @return State that updates with Flow emissions
 */
@Composable
fun <T> Flow<T>.collectAsState(
    initial: T,
    context: CoroutineContext = EmptyCoroutineContext
): State<T>

/**
 * Collects values from a StateFlow and represents them as State
 * Uses the StateFlow's current value as initial value
 * @param context CoroutineContext for collection (default: EmptyCoroutineContext)
 * @return State that updates with StateFlow emissions
 */
@Composable
fun <T> StateFlow<T>.collectAsState(
    context: CoroutineContext = EmptyCoroutineContext
): State<T>

Usage Examples:

@Composable
fun FlowCollectionExample(repository: DataRepository) {
    // Collect list data from Flow
    val items by repository.getItemsFlow().collectAsState(
        initial = emptyList()
    )
    
    // Collect search results
    val searchQuery by repository.searchQueryFlow().collectAsState(
        initial = ""
    )
    
    val filteredItems = remember(items, searchQuery) {
        if (searchQuery.isEmpty()) items else items.filter { 
            it.name.contains(searchQuery, ignoreCase = true) 
        }
    }
    
    LazyColumn {
        items(filteredItems) { item ->
            ItemRow(item = item)
        }
    }
}

@Composable
fun ViewModelExample(viewModel: MyViewModel) {
    // Collect UI state from ViewModel
    val uiState by viewModel.uiState.collectAsState()
    
    // Collect loading state
    val isLoading by viewModel.isLoading.collectAsState()
    
    when (uiState) {
        is UiState.Loading -> LoadingIndicator()
        is UiState.Success -> {
            SuccessContent(
                data = uiState.data,
                isRefreshing = isLoading
            )
        }
        is UiState.Error -> ErrorMessage(uiState.message)
    }
}

List Extensions

Useful extensions for working with state lists.

/**
 * Converts a regular List to a SnapshotStateList
 */
fun <T> List<T>.toMutableStateList(): SnapshotStateList<T>

/**
 * Creates a state list from a collection
 */
fun <T> Collection<T>.toMutableStateList(): SnapshotStateList<T>

Usage Examples:

@Composable
fun ListConversionExample() {
    // Convert existing list to state list
    val originalList = listOf("A", "B", "C")
    val stateList = remember { originalList.toMutableStateList() }
    
    // Now mutations will trigger recomposition
    Button(onClick = { stateList.add("D") }) {
        Text("Add D")
    }
}

@Composable
fun DataLoadingExample(initialData: List<String>) {
    val items = remember(initialData) { 
        initialData.toMutableStateList() 
    }
    
    LaunchedEffect(Unit) {
        val newItems = loadAdditionalData()
        items.addAll(newItems)
    }
    
    LazyColumn {
        items(items) { item ->
            Text(item)
        }
    }
}

Snapshot System Integration

Advanced usage of the snapshot system underlying state collections.

/**
 * Takes a snapshot of the current state
 * @return Snapshot instance
 */
fun Snapshot.Companion.take(): Snapshot

/**
 * Creates a mutable snapshot for making isolated changes
 */
fun Snapshot.Companion.takeMutableSnapshot(
    readObserver: ((Any) -> Unit)? = null,
    writeObserver: ((Any) -> Unit)? = null
): MutableSnapshot

/**
 * Base class for snapshots of the state system
 */
abstract class Snapshot {
    companion object
    
    /**
     * Applies changes made in this snapshot
     * @return SnapshotApplyResult indicating success or conflicts
     */
    abstract fun apply(): SnapshotApplyResult
    
    /**
     * Disposes of this snapshot, releasing resources
     */
    abstract fun dispose()
}

/**
 * A mutable snapshot that allows making changes within an isolated scope
 */
abstract class MutableSnapshot : Snapshot {
    /**
     * Enters the snapshot scope for making changes
     */
    abstract fun <T> enter(block: () -> T): T
}

/**
 * Result of applying a snapshot
 */
sealed class SnapshotApplyResult {
    object Success : SnapshotApplyResult()
    data class Failure(val snapshot: Snapshot) : SnapshotApplyResult()
}

Usage Examples:

@Composable
fun SnapshotExample() {
    val items = remember { mutableStateListOf("A", "B", "C") }
    
    Button(
        onClick = {
            // Make changes in an isolated snapshot
            val snapshot = Snapshot.takeMutableSnapshot()
            snapshot.enter {
                items.add("D")
                items.add("E")
                // Changes aren't visible yet
            }
            
            // Apply changes atomically
            snapshot.apply()
            snapshot.dispose()
        }
    ) {
        Text("Add Multiple Items")
    }
}

Collection Patterns

Filtered Collections

Create derived collections that update automatically.

@Composable
fun FilteredCollectionExample() {
    val allItems = remember { mutableStateListOf<Item>() }
    var filterText by remember { mutableStateOf("") }
    
    val filteredItems = remember(allItems, filterText) {
        derivedStateOf {
            if (filterText.isEmpty()) {
                allItems.toList()
            } else {
                allItems.filter { it.name.contains(filterText, ignoreCase = true) }
            }
        }
    }.value
    
    Column {
        TextField(
            value = filterText,
            onValueChange = { filterText = it },
            label = { Text("Filter") }
        )
        
        LazyColumn {
            items(filteredItems) { item ->
                ItemCard(item = item)
            }
        }
    }
}

Grouped Collections

Group collections by key with automatic updates.

@Composable
fun GroupedCollectionExample() {
    val items = remember { mutableStateListOf<Task>() }
    
    val groupedItems = remember(items) {
        derivedStateOf {
            items.groupBy { it.category }
        }
    }.value
    
    LazyColumn {
        groupedItems.forEach { (category, tasks) ->
            item {
                Text(
                    text = category,
                    style = MaterialTheme.typography.h6
                )
            }
            
            items(tasks) { task ->
                TaskItem(task = task)
            }
        }
    }
}

Sorted Collections

Maintain sorted collections that update automatically.

@Composable
fun SortedCollectionExample() {
    val items = remember { mutableStateListOf<Product>() }
    var sortBy by remember { mutableStateOf(SortCriteria.NAME) }
    
    val sortedItems = remember(items, sortBy) {
        derivedStateOf {
            when (sortBy) {
                SortCriteria.NAME -> items.sortedBy { it.name }
                SortCriteria.PRICE -> items.sortedBy { it.price }
                SortCriteria.RATING -> items.sortedByDescending { it.rating }
            }
        }
    }.value
    
    Column {
        SortingOptions(
            currentSort = sortBy,
            onSortChange = { sortBy = it }
        )
        
        LazyColumn {
            items(sortedItems) { product ->
                ProductCard(product = product)
            }
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-runtime--runtime-desktop

docs

collections.md

composition.md

effects.md

index.md

state-management.md

tile.json