Skip to content

Commit 38e4576

Browse files
committed
Add noCache(() and onlyIfCached()
1 parent 9cf23bc commit 38e4576

5 files changed

Lines changed: 102 additions & 30 deletions

File tree

normalized-cache/api/normalized-cache.api

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ public final class com/apollographql/cache/normalized/FetchPolicyInterceptors {
147147
public static final fun getCacheAndNetworkInterceptor ()Lcom/apollographql/apollo/interceptor/ApolloInterceptor;
148148
public static final fun getCacheFirstInterceptor ()Lcom/apollographql/apollo/interceptor/ApolloInterceptor;
149149
public static final fun getCacheOnlyInterceptor ()Lcom/apollographql/apollo/interceptor/ApolloInterceptor;
150+
public static final fun getDonkeyInterceptor ()Lcom/apollographql/apollo/interceptor/ApolloInterceptor;
150151
public static final fun getNetworkFirstInterceptor ()Lcom/apollographql/apollo/interceptor/ApolloInterceptor;
151152
public static final fun getNetworkOnlyInterceptor ()Lcom/apollographql/apollo/interceptor/ApolloInterceptor;
152153
}
@@ -180,7 +181,7 @@ public final class com/apollographql/cache/normalized/NormalizedCache {
180181
public static synthetic fun -logCacheMisses$default (Lcom/apollographql/apollo/ApolloClient$Builder;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/apollographql/apollo/ApolloClient$Builder;
181182
public static final fun addCacheHeader (Lcom/apollographql/apollo/api/MutableExecutionOptions;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
182183
public static final fun allowCachedErrors (Lcom/apollographql/apollo/api/MutableExecutionOptions;Z)Ljava/lang/Object;
183-
public static final fun allowPartialResults (Lcom/apollographql/apollo/api/MutableExecutionOptions;Z)Ljava/lang/Object;
184+
public static final fun allowCachedPartialResults (Lcom/apollographql/apollo/api/MutableExecutionOptions;Z)Ljava/lang/Object;
184185
public static final fun cacheHeaders (Lcom/apollographql/apollo/api/ApolloResponse$Builder;Lcom/apollographql/cache/normalized/api/CacheHeaders;)Lcom/apollographql/apollo/api/ApolloResponse$Builder;
185186
public static final fun cacheHeaders (Lcom/apollographql/apollo/api/MutableExecutionOptions;Lcom/apollographql/cache/normalized/api/CacheHeaders;)Ljava/lang/Object;
186187
public static final fun cacheManager (Lcom/apollographql/apollo/ApolloClient$Builder;Lcom/apollographql/cache/normalized/CacheManager;Z)Lcom/apollographql/apollo/ApolloClient$Builder;
@@ -209,7 +210,9 @@ public final class com/apollographql/cache/normalized/NormalizedCache {
209210
public static final fun isFromCache (Lcom/apollographql/apollo/api/ApolloResponse;)Z
210211
public static final fun maxStale-HG0u8IE (Lcom/apollographql/apollo/api/MutableExecutionOptions;J)Ljava/lang/Object;
211212
public static final fun memoryCacheOnly (Lcom/apollographql/apollo/api/MutableExecutionOptions;Z)Ljava/lang/Object;
213+
public static final fun noCache (Lcom/apollographql/apollo/api/MutableExecutionOptions;Z)Ljava/lang/Object;
212214
public static final fun normalizedCache-Tu6dINM (Lcom/apollographql/apollo/ApolloClient$Builder;Lcom/apollographql/cache/normalized/api/NormalizedCacheFactory;Ljava/util/Map;Ljava/util/Set;Ljava/util/Map;JLcom/apollographql/cache/normalized/api/CacheKey$Scope;ZZ)Lcom/apollographql/apollo/ApolloClient$Builder;
215+
public static final fun onlyIfCached (Lcom/apollographql/apollo/api/MutableExecutionOptions;Z)Ljava/lang/Object;
213216
public static final fun optimisticUpdates (Lcom/apollographql/apollo/ApolloCall;Lcom/apollographql/apollo/api/Mutation$Data;)Lcom/apollographql/apollo/ApolloCall;
214217
public static final fun optimisticUpdates (Lcom/apollographql/apollo/api/ApolloRequest$Builder;Lcom/apollographql/apollo/api/Mutation$Data;)Lcom/apollographql/apollo/api/ApolloRequest$Builder;
215218
public static final fun refetchPolicy (Lcom/apollographql/apollo/api/MutableExecutionOptions;Lcom/apollographql/cache/normalized/FetchPolicy;)Ljava/lang/Object;

normalized-cache/api/normalized-cache.klib.api

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,8 @@ final val com.apollographql.cache.normalized/CacheFirstInterceptor // com.apollo
592592
final fun <get-CacheFirstInterceptor>(): com.apollographql.apollo.interceptor/ApolloInterceptor // com.apollographql.cache.normalized/CacheFirstInterceptor.<get-CacheFirstInterceptor>|<get-CacheFirstInterceptor>(){}[0]
593593
final val com.apollographql.cache.normalized/CacheOnlyInterceptor // com.apollographql.cache.normalized/CacheOnlyInterceptor|{}CacheOnlyInterceptor[0]
594594
final fun <get-CacheOnlyInterceptor>(): com.apollographql.apollo.interceptor/ApolloInterceptor // com.apollographql.cache.normalized/CacheOnlyInterceptor.<get-CacheOnlyInterceptor>|<get-CacheOnlyInterceptor>(){}[0]
595+
final val com.apollographql.cache.normalized/DonkeyInterceptor // com.apollographql.cache.normalized/DonkeyInterceptor|{}DonkeyInterceptor[0]
596+
final fun <get-DonkeyInterceptor>(): com.apollographql.apollo.interceptor/ApolloInterceptor // com.apollographql.cache.normalized/DonkeyInterceptor.<get-DonkeyInterceptor>|<get-DonkeyInterceptor>(){}[0]
595597
final val com.apollographql.cache.normalized/NetworkFirstInterceptor // com.apollographql.cache.normalized/NetworkFirstInterceptor|{}NetworkFirstInterceptor[0]
596598
final fun <get-NetworkFirstInterceptor>(): com.apollographql.apollo.interceptor/ApolloInterceptor // com.apollographql.cache.normalized/NetworkFirstInterceptor.<get-NetworkFirstInterceptor>|<get-NetworkFirstInterceptor>(){}[0]
597599
final val com.apollographql.cache.normalized/NetworkOnlyInterceptor // com.apollographql.cache.normalized/NetworkOnlyInterceptor|{}NetworkOnlyInterceptor[0]
@@ -633,7 +635,7 @@ final fun <#A: com.apollographql.apollo.api/Query.Data> (com.apollographql.apoll
633635
final fun <#A: com.apollographql.apollo.api/Query.Data> (com.apollographql.apollo/ApolloCall<#A>).com.apollographql.cache.normalized/watch(): kotlinx.coroutines.flow/Flow<com.apollographql.apollo.api/ApolloResponse<#A>> // com.apollographql.cache.normalized/watch|watch@com.apollographql.apollo.ApolloCall<0:0>(){0§<com.apollographql.apollo.api.Query.Data>}[0]
634636
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/addCacheHeader(kotlin/String, kotlin/String): #A // com.apollographql.cache.normalized/addCacheHeader|addCacheHeader@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.String;kotlin.String){0§<kotlin.Any?>}[0]
635637
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/allowCachedErrors(kotlin/Boolean): #A // com.apollographql.cache.normalized/allowCachedErrors|allowCachedErrors@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]
636-
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/allowPartialResults(kotlin/Boolean): #A // com.apollographql.cache.normalized/allowPartialResults|allowPartialResults@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]
638+
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/allowCachedPartialResults(kotlin/Boolean): #A // com.apollographql.cache.normalized/allowCachedPartialResults|allowCachedPartialResults@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]
637639
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/cacheHeaders(com.apollographql.cache.normalized.api/CacheHeaders): #A // com.apollographql.cache.normalized/cacheHeaders|cacheHeaders@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(com.apollographql.cache.normalized.api.CacheHeaders){0§<kotlin.Any?>}[0]
638640
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/clock(kotlin/Function0<kotlin/Long>): #A // com.apollographql.cache.normalized/clock|clock@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Function0<kotlin.Long>){0§<kotlin.Any?>}[0]
639641
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/doNotStore(kotlin/Boolean): #A // com.apollographql.cache.normalized/doNotStore|doNotStore@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]
@@ -642,6 +644,8 @@ final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOption
642644
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/fetchPolicyInterceptor(com.apollographql.apollo.interceptor/ApolloInterceptor): #A // com.apollographql.cache.normalized/fetchPolicyInterceptor|fetchPolicyInterceptor@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(com.apollographql.apollo.interceptor.ApolloInterceptor){0§<kotlin.Any?>}[0]
643645
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/maxStale(kotlin.time/Duration): #A // com.apollographql.cache.normalized/maxStale|maxStale@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.time.Duration){0§<kotlin.Any?>}[0]
644646
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/memoryCacheOnly(kotlin/Boolean): #A // com.apollographql.cache.normalized/memoryCacheOnly|memoryCacheOnly@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]
647+
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/noCache(kotlin/Boolean): #A // com.apollographql.cache.normalized/noCache|noCache@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]
648+
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/onlyIfCached(kotlin/Boolean): #A // com.apollographql.cache.normalized/onlyIfCached|onlyIfCached@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]
645649
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/refetchPolicy(com.apollographql.cache.normalized/FetchPolicy): #A // com.apollographql.cache.normalized/refetchPolicy|refetchPolicy@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(com.apollographql.cache.normalized.FetchPolicy){0§<kotlin.Any?>}[0]
646650
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/refetchPolicyInterceptor(com.apollographql.apollo.interceptor/ApolloInterceptor): #A // com.apollographql.cache.normalized/refetchPolicyInterceptor|refetchPolicyInterceptor@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(com.apollographql.apollo.interceptor.ApolloInterceptor){0§<kotlin.Any?>}[0]
647651
final fun <#A: kotlin/Any?> (com.apollographql.apollo.api/MutableExecutionOptions<#A>).com.apollographql.cache.normalized/storeExpirationDate(kotlin/Boolean): #A // com.apollographql.cache.normalized/storeExpirationDate|storeExpirationDate@com.apollographql.apollo.api.MutableExecutionOptions<0:0>(kotlin.Boolean){0§<kotlin.Any?>}[0]

normalized-cache/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -754,28 +754,57 @@ fun <T> MutableExecutionOptions<T>.clock(clock: () -> Long): T {
754754
return this as T
755755
}
756756

757-
internal class AllowPartialResults(val value: Boolean) : ExecutionContext.Element {
757+
internal class AllowCachedPartialResultsContext(val value: Boolean) : ExecutionContext.Element {
758758
override val key: ExecutionContext.Key<*>
759759
get() = Key
760760

761-
companion object Key : ExecutionContext.Key<AllowPartialResults>
761+
companion object Key : ExecutionContext.Key<AllowCachedPartialResultsContext>
762762
}
763763

764-
internal val ExecutionOptions.allowPartialResults: Boolean
765-
get() = executionContext[AllowPartialResults]?.value ?: false
764+
internal val ExecutionOptions.allowCachedPartialResults: Boolean
765+
get() = executionContext[AllowCachedPartialResultsContext]?.value ?: false
766766

767-
fun <T> MutableExecutionOptions<T>.allowPartialResults(allowPartialResults: Boolean): T =
768-
addExecutionContext(AllowPartialResults(allowPartialResults))
767+
fun <T> MutableExecutionOptions<T>.allowCachedPartialResults(allowCachedPartialResults: Boolean): T =
768+
addExecutionContext(AllowCachedPartialResultsContext(allowCachedPartialResults))
769769

770-
internal class AllowCachedErrors(val value: Boolean) : ExecutionContext.Element {
770+
771+
internal class AllowCachedErrorsContext(val value: Boolean) : ExecutionContext.Element {
771772
override val key: ExecutionContext.Key<*>
772773
get() = Key
773774

774-
companion object Key : ExecutionContext.Key<AllowCachedErrors>
775+
companion object Key : ExecutionContext.Key<AllowCachedErrorsContext>
775776
}
776777

777778
internal val ExecutionOptions.allowCachedErrors: Boolean
778-
get() = executionContext[AllowCachedErrors]?.value ?: false
779+
get() = executionContext[AllowCachedErrorsContext]?.value ?: false
779780

780781
fun <T> MutableExecutionOptions<T>.allowCachedErrors(allowCachedErrors: Boolean): T =
781-
addExecutionContext(AllowCachedErrors(allowCachedErrors))
782+
addExecutionContext(AllowCachedErrorsContext(allowCachedErrors))
783+
784+
785+
internal class NoCacheContext(val value: Boolean) : ExecutionContext.Element {
786+
override val key: ExecutionContext.Key<*>
787+
get() = Key
788+
789+
companion object Key : ExecutionContext.Key<NoCacheContext>
790+
}
791+
792+
internal val ExecutionOptions.noCache: Boolean
793+
get() = executionContext[NoCacheContext]?.value ?: false
794+
795+
fun <T> MutableExecutionOptions<T>.noCache(noCache: Boolean): T =
796+
addExecutionContext(NoCacheContext(noCache))
797+
798+
799+
internal class OnlyIfCachedContext(val value: Boolean) : ExecutionContext.Element {
800+
override val key: ExecutionContext.Key<*>
801+
get() = Key
802+
803+
companion object Key : ExecutionContext.Key<OnlyIfCachedContext>
804+
}
805+
806+
internal val ExecutionOptions.onlyIfCached: Boolean
807+
get() = executionContext[OnlyIfCachedContext]?.value ?: false
808+
809+
fun <T> MutableExecutionOptions<T>.onlyIfCached(onlyIfCached: Boolean): T =
810+
addExecutionContext(OnlyIfCachedContext(onlyIfCached))

normalized-cache/src/commonMain/kotlin/com/apollographql/cache/normalized/FetchPolicyInterceptors.kt

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,35 @@ import kotlinx.coroutines.flow.onEach
2323
import kotlinx.coroutines.flow.single
2424
import kotlin.jvm.JvmName
2525

26+
// TODO: find a better name :_)
27+
val DonkeyInterceptor = object : ApolloInterceptor {
28+
override fun <D : Operation.Data> intercept(
29+
request: ApolloRequest<D>,
30+
chain: ApolloInterceptorChain,
31+
): Flow<ApolloResponse<D>> {
32+
return flow {
33+
if (!request.noCache) {
34+
val cacheResponse = chain.proceed(
35+
request = request
36+
.newBuilder()
37+
.fetchFromCache(true)
38+
.build()
39+
).single()
40+
.errorsAsException(allowCachedPartialResults = request.allowCachedPartialResults, allowCachedErrors = request.allowCachedErrors)
41+
emit(cacheResponse.newBuilder().isLast(request.onlyIfCached || cacheResponse.exception == null).build())
42+
if (cacheResponse.exception == null) {
43+
return@flow
44+
}
45+
}
46+
47+
if (!request.onlyIfCached) {
48+
val networkResponses = chain.proceed(request = request)
49+
emitAll(networkResponses)
50+
}
51+
}
52+
}
53+
}
54+
2655
/**
2756
* An interceptor that emits the response from the cache only.
2857
*/
@@ -34,7 +63,7 @@ val CacheOnlyInterceptor = object : ApolloInterceptor {
3463
.fetchFromCache(true)
3564
.build()
3665
).map {
37-
it.errorsAsException(allowPartialResults = request.allowPartialResults, allowCachedErrors = request.allowCachedErrors)
66+
it.errorsAsException(allowCachedPartialResults = request.allowCachedPartialResults, allowCachedErrors = request.allowCachedErrors)
3867
}
3968
}
4069
}
@@ -59,7 +88,8 @@ val CacheFirstInterceptor = object : ApolloInterceptor {
5988
.newBuilder()
6089
.fetchFromCache(true)
6190
.build()
62-
).single().errorsAsException(allowPartialResults = request.allowPartialResults, allowCachedErrors = request.allowCachedErrors)
91+
).single()
92+
.errorsAsException(allowCachedPartialResults = request.allowCachedPartialResults, allowCachedErrors = request.allowCachedErrors)
6393
emit(cacheResponse.newBuilder().isLast(cacheResponse.exception == null).build())
6494
if (cacheResponse.exception == null) {
6595
return@flow
@@ -105,7 +135,8 @@ val NetworkFirstInterceptor = object : ApolloInterceptor {
105135
.newBuilder()
106136
.fetchFromCache(true)
107137
.build()
108-
).single().errorsAsException(allowPartialResults = request.allowPartialResults, allowCachedErrors = request.allowCachedErrors)
138+
).single()
139+
.errorsAsException(allowCachedPartialResults = request.allowCachedPartialResults, allowCachedErrors = request.allowCachedErrors)
109140
emit(cacheResponse)
110141
}
111142
}
@@ -122,7 +153,8 @@ val CacheAndNetworkInterceptor = object : ApolloInterceptor {
122153
.newBuilder()
123154
.fetchFromCache(true)
124155
.build()
125-
).single().errorsAsException(allowPartialResults = request.allowPartialResults, allowCachedErrors = request.allowCachedErrors)
156+
).single()
157+
.errorsAsException(allowCachedPartialResults = request.allowCachedPartialResults, allowCachedErrors = request.allowCachedErrors)
126158

127159
emit(cacheResponse.newBuilder().isLast(false).build())
128160

@@ -153,13 +185,13 @@ fun <D : Operation.Data> ApolloResponse<D>.errorsAsException(): ApolloResponse<D
153185
}
154186

155187
private fun <D : Operation.Data> ApolloResponse<D>.errorsAsException(
156-
allowPartialResults: Boolean,
188+
allowCachedPartialResults: Boolean,
157189
allowCachedErrors: Boolean,
158190
): ApolloResponse<D> {
159-
return if (allowPartialResults && allowCachedErrors) {
191+
return if (allowCachedPartialResults && allowCachedErrors) {
160192
this
161193
} else {
162-
val cacheMissException = if (allowPartialResults) {
194+
val cacheMissException = if (allowCachedPartialResults) {
163195
null
164196
} else {
165197
errors.orEmpty().mapNotNull { it.cacheMissException }.reduceOrNull { acc, e ->

0 commit comments

Comments
 (0)