Package-level declarations

Types

Link copied to clipboard
class DecodedMutation<B : Any>(val endpoint: NetworkEndpoint, val body: B?, val bodyType: TypeInfo?)

The endpoint + body pair a MutationCodec reconstructs from a persisted payload. Distinct from QueuedMutation because it carries no MutationRecord.id/MutationRecord.key — those live on the record itself and are reattached by MutationQueue after decoding.

Link copied to clipboard

The default MutationStore: an in-memory map. Mutations enqueued with a MutationCodec are still tracked (so MutationQueue.restore works within the same process, e.g. after recreating a MutationQueue), but everything is lost on process death — use this when you don't need mutations to survive a relaunch, or as a reference implementation when writing a durable one.

Link copied to clipboard
interface MutationCodec<B : Any>

Bridges a specific mutation shape (one NetworkEndpoint implementation + body type) to and from a JSON string, so it can survive in a durable MutationStore and be replayed after the process restarts.

Link copied to clipboard
class MutationHandle(val id: String, val key: MutationKey)

Returned immediately by MutationQueue.enqueueMutation/enqueue. Execution happens in the background, so this carries no result — observe MutationQueue.statusFlow with key for outcome.

Link copied to clipboard
value class MutationKey(val value: String)

Identifies the logical mutation being made, independent of when it was enqueued.

Link copied to clipboard
class MutationQueue(apiClient: ApiClient, scope: CoroutineScope, store: MutationStore = InMemoryMutationStore(), defaultRetryPolicy: RetryPolicy = DefaultRetryPolicy(retryNonIdempotent = true), codecs: List<MutationCodec<*>> = emptyList())

Enqueues "forgivable" mutations (likes, follows, and similar fire-and-forget writes) for background execution with retry, instead of awaiting them inline from a ViewModel.

Link copied to clipboard
@Serializable
data class MutationRecord(val id: String, val key: String, val codecId: String, val payload: String, val enqueuedAtMillis: Long)

The fully serializable snapshot of one enqueued mutation that a MutationStore persists.

Link copied to clipboard
sealed class MutationStatus

The lifecycle of one enqueued mutation, as observed via MutationQueue.statusFlow.

Link copied to clipboard
interface MutationStore

Pluggable persistence for enqueued mutations, keyed by MutationRecord.id.

Link copied to clipboard
class QueuedMutation<B : Any>(val id: String, val key: MutationKey, val endpoint: NetworkEndpoint, val body: B?, val bodyType: TypeInfo?)

The live, in-process description of one enqueued mutation: which endpoint to call and what body to send. This is what MutationQueue actually executes via io.github.maniramezan.kenwork.network.ApiClient.request.

Functions

Link copied to clipboard
suspend fun MutationQueue.enqueue(key: MutationKey, endpoint: NetworkEndpoint, retryPolicy: RetryPolicy? = null): MutationHandle

Enqueues a bodyless mutation (e.g. POST /videos/42/like with no request body).

inline suspend fun <B : Any> MutationQueue.enqueue(key: MutationKey, endpoint: NetworkEndpoint, body: B, codec: MutationCodec<B>? = null, retryPolicy: RetryPolicy? = null): MutationHandle

Enqueues a mutation sending body of type B, serialized on execution.