Caches & Drafts

Last-synced payloads, an in-progress form, the "continue where you left off" blob — data that's useful but disposable, and should live apart from durable settings so it's easy to reason about (and to wipe) on its own.

@Serializable
data class SyncState(
    val lastSyncedAtEpochMs: Long = 0,
    val lastSyncedEtag: String = "",
)

@Serializable
data class DraftPost(
    val title: String = "",
    val body: String = "",
)

val cache = Documents.collection("cache")

val syncState = cache.document<SyncState>("sync-state")
val draft = cache.document<DraftPost>("compose-draft")

The compose screen writes to draft on every keystroke debounce, and reads it back on next launch to restore exactly where the user left off:

draft.update { current ->
    current.copy(body = textField.value)
}

// next launch
val restored = draft.get() ?: DraftPost()

Because cache is its own collection — its own MMKV file — clearing it out (a "reset cache" action, or a storage-pressure cleanup) never touches durable data living in the default store or another collection. See Collections & Testing for how collections isolate one set of documents from another.