Skip to content

Commit

Permalink
Merge pull request #17 from soil-kt/kdoc
Browse files Browse the repository at this point in the history
Add a KDoc comments for the soil.query package
  • Loading branch information
ogaclejapan committed May 6, 2024
2 parents 44e9b45 + 37e64c3 commit 186eba7
Show file tree
Hide file tree
Showing 51 changed files with 1,448 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ import android.content.res.Configuration
import soil.query.internal.MemoryPressure
import soil.query.internal.MemoryPressureLevel

/**
* Implementation of [MemoryPressure] for Android.
*
* In the Android system, [ComponentCallbacks2] is used to monitor memory pressure states.
* It notifies the memory pressure state based on the level parameter of [ComponentCallbacks2.onTrimMemory].
*
* | Android Trim Level | MemoryPressureLevel |
* |:-------------------------------|:----------------------|
* | TRIM_MEMORY_UI_HIDDEN | Low |
* | TRIM_MEMORY_MODERATE | Low |
* | TRIM_MEMORY_RUNNING_MODERATE | Low |
* | TRIM_MEMORY_BACKGROUND | High |
* | TRIM_MEMORY_RUNNING_LOW | High |
* | TRIM_MEMORY_COMPLETE | Critical |
* | TRIM_MEMORY_RUNNING_CRITICAL | Critical |
*
*/
class AndroidMemoryPressure(
private val context: Context
) : MemoryPressure {
Expand All @@ -23,6 +40,9 @@ class AndroidMemoryPressure(
obw = null
}

/**
* Implementation of [ComponentCallbacks2] for observing memory pressure.
*/
class ObserverWrapper(
private val observer: MemoryPressure.Observer
) : ComponentCallbacks2 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ import androidx.annotation.RequiresPermission
import soil.query.internal.NetworkConnectivity
import soil.query.internal.NetworkConnectivityEvent

/**
* Implementation of [NetworkConnectivity] for Android.
*
* In the Android system, [ConnectivityManager] is used to monitor network connectivity states.
*
* **Note**: This implementation requires the `ACCESS_NETWORK_STATE` permission.
*
* ```
* <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
* ```
*/
class AndroidNetworkConnectivity(
private val context: Context
) : NetworkConnectivity {
Expand All @@ -37,6 +48,9 @@ class AndroidNetworkConnectivity(
obw = null
}

/**
* Implementation of [ConnectivityManager.NetworkCallback] for observing network connectivity.
*/
class ObserverWrapper(
private val observer: NetworkConnectivity.Observer
) : ConnectivityManager.NetworkCallback() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import androidx.lifecycle.ProcessLifecycleOwner
import soil.query.internal.WindowVisibility
import soil.query.internal.WindowVisibilityEvent

/**
* Implementation of [WindowVisibility] for Android.
*
* In the Android system, [ProcessLifecycleOwner] is used to monitor window visibility states.
* It notifies the window visibility state based on the lifecycle state of [ProcessLifecycleOwner].
*/
class AndroidWindowVisibility(
private val lifecycleOwner: LifecycleOwner = ProcessLifecycleOwner.get()
) : WindowVisibility {
Expand All @@ -36,6 +42,9 @@ class AndroidWindowVisibility(
}
}

/**
* Implementation of [DefaultLifecycleObserver] for observing window visibility.
*/
class CallbackWrapper(
private val callback: WindowVisibility.Observer
) : DefaultLifecycleObserver {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ import soil.query.internal.RetryFn
import soil.query.internal.exponentialBackOff
import kotlin.coroutines.cancellation.CancellationException

/**
* Fetches data for the [InfiniteQueryKey] using the value of [variable].
*
* @receiver [QueryCommand.Context] for [InfiniteQueryKey].
* @param T Type of data to retrieve.
* @param S Type of parameter.
* @param key Instance of a class implementing [InfiniteQueryKey].
* @param variable Value of the parameter required for fetching data for [InfiniteQueryKey].
* @param retryFn Retry strategy.
*/
suspend fun <T, S> QueryCommand.Context<QueryChunks<T, S>>.fetch(
key: InfiniteQueryKey<T, S>,
variable: S,
Expand All @@ -22,6 +32,15 @@ suspend fun <T, S> QueryCommand.Context<QueryChunks<T, S>>.fetch(
}
}

/**
* Revalidates the data for the [InfiniteQueryKey] using the value of [chunks].
*
* @receiver [QueryCommand.Context] for [InfiniteQueryKey].
* @param T Type of data to retrieve.
* @param S Type of parameter.
* @param key Instance of a class implementing [InfiniteQueryKey].
* @param chunks Data to revalidate.
*/
suspend fun <T, S> QueryCommand.Context<QueryChunks<T, S>>.revalidate(
key: InfiniteQueryKey<T, S>,
chunks: QueryChunks<T, S>
Expand All @@ -47,6 +66,15 @@ suspend fun <T, S> QueryCommand.Context<QueryChunks<T, S>>.revalidate(
return Result.success(newData)
}

/**
* Dispatches the result of fetching data for the [InfiniteQueryKey].
*
* @receiver [QueryCommand.Context] for [InfiniteQueryKey].
* @param T Type of data to retrieve.
* @param S Type of parameter.
* @param key Instance of a class implementing [InfiniteQueryKey].
* @param variable Value of the parameter required for fetching data for [InfiniteQueryKey].
*/
suspend inline fun <T, S> QueryCommand.Context<QueryChunks<T, S>>.dispatchFetchChunksResult(
key: InfiniteQueryKey<T, S>,
variable: S
Expand All @@ -59,6 +87,15 @@ suspend inline fun <T, S> QueryCommand.Context<QueryChunks<T, S>>.dispatchFetchC
.onFailure(::dispatchFetchFailure)
}

/**
* Dispatches the result of revalidating data for the [InfiniteQueryKey].
*
* @receiver [QueryCommand.Context] for [InfiniteQueryKey].
* @param T Type of data to retrieve.
* @param S Type of parameter.
* @param key Instance of a class implementing [InfiniteQueryKey].
* @param chunks Data to revalidate.
*/
suspend inline fun <T, S> QueryCommand.Context<QueryChunks<T, S>>.dispatchRevalidateChunksResult(
key: InfiniteQueryKey<T, S>,
chunks: QueryChunks<T, S>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,22 @@ package soil.query

import soil.query.internal.vvv

/**
* Query command for [InfiniteQueryKey].
*
* @param T Type of data to retrieve.
* @param S Type of parameter.
*/
sealed class InfiniteQueryCommands<T, S> : QueryCommand<QueryChunks<T, S>> {

/**
* Performs data fetching and validation based on the current data state.
*
* This command is invoked via [InfiniteQueryRef] when a new mount point (subscriber) is added.
*
* @param key Instance of a class implementing [InfiniteQueryKey].
* @param revision The revision of the data to be fetched.
*/
data class Connect<T, S>(
val key: InfiniteQueryKey<T, S>,
val revision: String? = null
Expand All @@ -26,6 +40,14 @@ sealed class InfiniteQueryCommands<T, S> : QueryCommand<QueryChunks<T, S>> {
}
}

/**
* Invalidates the data and performs data fetching and validation based on the current data state.
*
* This command is invoked via [InfiniteQueryRef] when the data is invalidated.
*
* @param key Instance of a class implementing [InfiniteQueryKey].
* @param revision The revision of the data to be invalidated.
*/
data class Invalidate<T, S>(
val key: InfiniteQueryKey<T, S>,
val revision: String
Expand All @@ -45,6 +67,12 @@ sealed class InfiniteQueryCommands<T, S> : QueryCommand<QueryChunks<T, S>> {
}
}

/**
* Fetches additional data for [InfiniteQueryKey] using [param].
*
* @param key Instance of a class implementing [InfiniteQueryKey].
* @param param The parameter required for fetching data for [InfiniteQueryKey].
*/
data class LoadMore<T, S>(
val key: InfiniteQueryKey<T, S>,
val param: S
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,69 @@ package soil.query
import soil.query.internal.SurrogateKey
import soil.query.internal.UniqueId

/**
* [InfiniteQueryKey] for managing [Query] associated with [id].
*
* The difference from [QueryKey] is that it's an interface for infinite fetching data using a retrieval method known as "infinite scroll."
*
* @param T Type of data to retrieve.
* @param S Type of parameter.
*/
interface InfiniteQueryKey<T, S> {

/**
* A unique identifier used for managing [InfiniteQueryKey].
*/
val id: InfiniteQueryId<T, S>

/**
* Suspending function to retrieve data.
*
* @receiver QueryReceiver You can use a custom QueryReceiver within the fetch function.
*/
val fetch: suspend QueryReceiver.(param: S) -> T

/**
* Function returning the initial parameter.
*/
val initialParam: () -> S

/**
* Function returning the parameter for additional fetching.
*
* `chunks` contains the retrieved data.
*/
val loadMoreParam: (chunks: QueryChunks<T, S>) -> S?

/**
* Configure the Query [options].
*
* If unspecified, the default value of [SwrCachePolicy] is used.
*/
val options: QueryOptions?

/**
* Function to specify placeholder data.
*
* You can specify placeholder data instead of the initial loading state.
*
* @see QueryPlaceholderData
*/
fun onPlaceholderData(): QueryPlaceholderData<QueryChunks<T, S>>? = null

/**
* Function to convert specific exceptions as data.
*
* Depending on the type of exception that occurred during data retrieval, it is possible to recover it as normal data.
*
* @see QueryRecoverData
*/
fun onRecoverData(): QueryRecoverData<QueryChunks<T, S>>? = null
}

/**
* Unique identifier for [InfiniteQueryKey].
*/
@Suppress("unused")
open class InfiniteQueryId<T, S>(
override val namespace: String,
Expand Down Expand Up @@ -46,6 +97,22 @@ internal fun <T, S> InfiniteQueryKey<T, S>.hasMore(chunks: QueryChunks<T, S>): B
return loadMoreParam(chunks) != null
}

/**
* Function for building implementations of [InfiniteQueryKey] using [Kotlin Delegation](https://kotlinlang.org/docs/delegation.html).
*
* **Note:** By implementing through delegation, you can reduce the impact of future changes to [InfiniteQueryKey] interface extensions.
*
* Usage:
*
* ```kotlin
* class GetPostsKey(userId: Int? = null) : InfiniteQueryKey<Posts, PageParam> by buildInfiniteQueryKey(
* id = Id(userId),
* fetch = { param -> ... }
* initialParam = { PageParam(limit = 20) },
* loadMoreParam = { chunks -> ... }
* )
* ```
*/
fun <T, S> buildInfiniteQueryKey(
id: InfiniteQueryId<T, S>,
fetch: suspend QueryReceiver.(param: S) -> T,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.launch

/**
* A reference to an [Query] for [InfiniteQueryKey].
*
* @param T Type of data to retrieve.
* @param S Type of parameter.
* @property key Instance of a class implementing [InfiniteQueryKey].
* @param query Transparently referenced [Query].
* @constructor Creates an [InfiniteQueryRef].
*/
class InfiniteQueryRef<T, S>(
val key: InfiniteQueryKey<T, S>,
query: Query<QueryChunks<T, S>>
) : Query<QueryChunks<T, S>> by query {

/**
* Starts the [Query].
*
* This function must be invoked when a new mount point (subscriber) is added.
*
* @param scope The [CoroutineScope] to launch the [Query] actor.
*/
fun start(scope: CoroutineScope) {
actor.launchIn(scope = scope)
scope.launch {
Expand All @@ -20,14 +36,26 @@ class InfiniteQueryRef<T, S>(
}
}

/**
* Invalidates the [Query].
*
* Calling this function will invalidate the retrieved data of the [Query],
* setting [QueryModel.isInvalidated] to `true` until revalidation is completed.
*/
suspend fun invalidate() {
command.send(InfiniteQueryCommands.Invalidate(key, state.value.revision))
}

/**
* Resumes the [Query].
*/
private suspend fun resume() {
command.send(InfiniteQueryCommands.Connect(key, state.value.revision))
}

/**
* Fetches data for the [InfiniteQueryKey] using the value of [param].
*/
suspend fun loadMore(param: S) {
command.send(InfiniteQueryCommands.LoadMore(key, param))
}
Expand Down
24 changes: 24 additions & 0 deletions soil-query-core/src/commonMain/kotlin/soil/query/Mutation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,37 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow

/**
* Mutation as the base interface for an [MutationClient] implementations.
*
* @param T Type of the return value from the mutation.
*/
interface Mutation<T> {

/**
* Coroutine [Flow] to launch the actor.
*/
val actor: Flow<*>

/**
* [Shared Flow][SharedFlow] to receive mutation [events][MutationEvent].
*/
val event: SharedFlow<MutationEvent>

/**
* [State Flow][StateFlow] to receive the current state of the mutation.
*/
val state: StateFlow<MutationState<T>>

/**
* [Send Channel][SendChannel] to manipulate the state of the mutation.
*/
val command: SendChannel<MutationCommand<T>>
}

/**
* Events occurring in the mutation.
*/
enum class MutationEvent {
Ping
}

0 comments on commit 186eba7

Please sign in to comment.