diff --git a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt index 505a600a..088926f5 100644 --- a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt +++ b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt @@ -4,18 +4,27 @@ package com.apollographql.cache.apollocompilerplugin.internal import com.apollographql.apollo.annotations.ApolloExperimental import com.apollographql.apollo.ast.GQLDocument +import com.apollographql.apollo.ast.GQLInterfaceTypeDefinition +import com.apollographql.apollo.ast.GQLObjectTypeDefinition +import com.apollographql.apollo.ast.GQLStringValue +import com.apollographql.apollo.ast.GQLUnionTypeDefinition import com.apollographql.apollo.ast.Schema +import com.apollographql.apollo.ast.Schema.Companion.TYPE_POLICY import com.apollographql.apollo.ast.toSchema import com.apollographql.apollo.compiler.ApolloCompilerPluginEnvironment import com.apollographql.apollo.compiler.SchemaCodeGenerator import com.apollographql.cache.apollocompilerplugin.VERSION +import com.squareup.kotlinpoet.BOOLEAN import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.MAP import com.squareup.kotlinpoet.MemberName +import com.squareup.kotlinpoet.ParameterSpec import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.SET import com.squareup.kotlinpoet.STRING import com.squareup.kotlinpoet.TypeSpec import com.squareup.kotlinpoet.asTypeName @@ -29,6 +38,11 @@ private object Symbols { val MaxAgeDuration = MaxAge.nestedClass("Duration") val Seconds = MemberName(Duration.Companion::class.asTypeName(), "seconds", isExtension = true) val TypePolicy = ClassName("com.apollographql.cache.normalized.api", "TypePolicy") + val ApolloClientBuilder = ClassName("com.apollographql.apollo", "ApolloClient", "Builder") + val NormalizedCacheFactory = ClassName("com.apollographql.cache.normalized.api", "NormalizedCacheFactory") + val CacheKeyScope = ClassName("com.apollographql.cache.normalized.api", "CacheKey", "Scope") + val KotlinDuration = Duration::class.asTypeName() + val NormalisedCacheExtension = MemberName("com.apollographql.cache.normalized", "normalizedCache", isExtension = true) } internal class CacheSchemaCodeGenerator( @@ -43,6 +57,8 @@ internal class CacheSchemaCodeGenerator( TypeSpec.objectBuilder("Cache") .addProperty(maxAgeProperty(validSchema)) .addProperty(typePoliciesProperty(validSchema)) + .addProperty(connectionTypesProperty(validSchema, packageName)) + .addFunction(cacheFunction(validSchema)) .build() ) .addFileComment( @@ -111,4 +127,69 @@ internal class CacheSchemaCodeGenerator( .initializer(initializer) .build() } + + private fun connectionTypesProperty(schema: Schema, packageName: String): PropertySpec { + // TODO: connectionTypes is generated by the Apollo compiler for now, and we just reference it. Instead we should generate it here. + val hasPagination = schema.hasConnectionFields() + val initializer = if (hasPagination) { + val paginationPackageName = packageName.substringBeforeLast(".") + ".pagination" + CodeBlock.of("%T.connectionTypes", ClassName(paginationPackageName, "Pagination")) + } else { + CodeBlock.of("emptySet()") + } + return PropertySpec.builder( + name = "connectionTypes", + type = SET.parameterizedBy(STRING) + ) + .initializer(initializer) + .build() + } + + private fun cacheFunction(validSchema: Schema): FunSpec { + validSchema.hasConnectionFields() + return FunSpec.builder("cache") + .receiver(Symbols.ApolloClientBuilder) + .addParameter("normalizedCacheFactory", Symbols.NormalizedCacheFactory) + .addParameter(ParameterSpec.builder("keyScope", Symbols.CacheKeyScope) + .defaultValue("CacheKey.Scope.TYPE").build() + ) + .addParameter(ParameterSpec.builder("defaultMaxAge", Symbols.KotlinDuration) + .defaultValue("%T.INFINITE", Symbols.KotlinDuration) + .build() + ) + .addParameter(ParameterSpec.builder("writeToCacheAsynchronously", BOOLEAN) + .defaultValue("false") + .build() + ) + .returns(Symbols.ApolloClientBuilder) + .addCode( + CodeBlock.builder() + .addStatement( + "return %M(\n⇥" + + "normalizedCacheFactory = normalizedCacheFactory,\n" + + "typePolicies = typePolicies,\n" + + "connectionTypes = connectionTypes, \n" + + "maxAges = maxAges,\n" + + "defaultMaxAge = defaultMaxAge,\n" + + "keyScope = keyScope,\n" + + "writeToCacheAsynchronously = writeToCacheAsynchronously,\n⇤" + + ")", + Symbols.NormalisedCacheExtension, + ) + .build() + ) + .build() + } + + private fun Schema.hasConnectionFields(): Boolean { + val directives = typeDefinitions.values.filterIsInstance().flatMap { it.directives } + + typeDefinitions.values.filterIsInstance().flatMap { it.directives } + + typeDefinitions.values.filterIsInstance().flatMap { it.directives } + return directives.any { + originalDirectiveName(it.name) == TYPE_POLICY && + it.arguments.any { arg -> + arg.name == "connectionFields" && !(arg.value as? GQLStringValue)?.value.isNullOrBlank() + } + } + } } diff --git a/normalized-cache/api/normalized-cache.api b/normalized-cache/api/normalized-cache.api index 0fa7347f..94230f75 100644 --- a/normalized-cache/api/normalized-cache.api +++ b/normalized-cache/api/normalized-cache.api @@ -205,6 +205,7 @@ public final class com/apollographql/cache/normalized/NormalizedCache { public static final fun isFromCache (Lcom/apollographql/apollo/api/ApolloResponse;)Z public static final fun maxStale-HG0u8IE (Lcom/apollographql/apollo/api/MutableExecutionOptions;J)Ljava/lang/Object; public static final fun memoryCacheOnly (Lcom/apollographql/apollo/api/MutableExecutionOptions;Z)Ljava/lang/Object; + public static final fun normalizedCache-HOFDmpg (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;Z)Lcom/apollographql/apollo/ApolloClient$Builder; public static final fun optimisticUpdates (Lcom/apollographql/apollo/ApolloCall;Lcom/apollographql/apollo/api/Mutation$Data;)Lcom/apollographql/apollo/ApolloCall; public static final fun optimisticUpdates (Lcom/apollographql/apollo/api/ApolloRequest$Builder;Lcom/apollographql/apollo/api/Mutation$Data;)Lcom/apollographql/apollo/api/ApolloRequest$Builder; public static final fun refetchPolicy (Lcom/apollographql/apollo/api/MutableExecutionOptions;Lcom/apollographql/cache/normalized/FetchPolicy;)Ljava/lang/Object; diff --git a/normalized-cache/api/normalized-cache.klib.api b/normalized-cache/api/normalized-cache.klib.api index 021addce..e31e6895 100644 --- a/normalized-cache/api/normalized-cache.klib.api +++ b/normalized-cache/api/normalized-cache.klib.api @@ -613,6 +613,7 @@ final val com.apollographql.cache.normalized/isFromCache // com.apollographql.ca final fun (com.apollographql.apollo/ApolloClient.Builder).com.apollographql.cache.normalized/cacheManager(com.apollographql.cache.normalized/CacheManager, kotlin/Boolean = ...): com.apollographql.apollo/ApolloClient.Builder // com.apollographql.cache.normalized/cacheManager|cacheManager@com.apollographql.apollo.ApolloClient.Builder(com.apollographql.cache.normalized.CacheManager;kotlin.Boolean){}[0] final fun (com.apollographql.apollo/ApolloClient.Builder).com.apollographql.cache.normalized/logCacheMisses(kotlin/Function1 = ...): com.apollographql.apollo/ApolloClient.Builder // com.apollographql.cache.normalized/logCacheMisses|logCacheMisses@com.apollographql.apollo.ApolloClient.Builder(kotlin.Function1){}[0] final fun (com.apollographql.apollo/ApolloClient.Builder).com.apollographql.cache.normalized/normalizedCache(com.apollographql.cache.normalized.api/NormalizedCacheFactory, com.apollographql.cache.normalized.api/CacheKeyGenerator = ..., com.apollographql.cache.normalized.api/MetadataGenerator = ..., com.apollographql.cache.normalized.api/CacheResolver = ..., com.apollographql.cache.normalized.api/RecordMerger = ..., com.apollographql.cache.normalized.api/FieldKeyGenerator = ..., com.apollographql.cache.normalized.api/EmbeddedFieldsProvider = ..., com.apollographql.cache.normalized.api/MaxAgeProvider = ..., kotlin/Boolean = ...): com.apollographql.apollo/ApolloClient.Builder // com.apollographql.cache.normalized/normalizedCache|normalizedCache@com.apollographql.apollo.ApolloClient.Builder(com.apollographql.cache.normalized.api.NormalizedCacheFactory;com.apollographql.cache.normalized.api.CacheKeyGenerator;com.apollographql.cache.normalized.api.MetadataGenerator;com.apollographql.cache.normalized.api.CacheResolver;com.apollographql.cache.normalized.api.RecordMerger;com.apollographql.cache.normalized.api.FieldKeyGenerator;com.apollographql.cache.normalized.api.EmbeddedFieldsProvider;com.apollographql.cache.normalized.api.MaxAgeProvider;kotlin.Boolean){}[0] +final fun (com.apollographql.apollo/ApolloClient.Builder).com.apollographql.cache.normalized/normalizedCache(com.apollographql.cache.normalized.api/NormalizedCacheFactory, kotlin.collections/Map, kotlin.collections/Set, kotlin.collections/Map, kotlin.time/Duration, com.apollographql.cache.normalized.api/CacheKey.Scope, kotlin/Boolean): com.apollographql.apollo/ApolloClient.Builder // com.apollographql.cache.normalized/normalizedCache|normalizedCache@com.apollographql.apollo.ApolloClient.Builder(com.apollographql.cache.normalized.api.NormalizedCacheFactory;kotlin.collections.Map;kotlin.collections.Set;kotlin.collections.Map;kotlin.time.Duration;com.apollographql.cache.normalized.api.CacheKey.Scope;kotlin.Boolean){}[0] final fun (com.apollographql.cache.normalized.api/Record).com.apollographql.cache.normalized.api/expirationDate(kotlin/String): kotlin/Long? // com.apollographql.cache.normalized.api/expirationDate|expirationDate@com.apollographql.cache.normalized.api.Record(kotlin.String){}[0] final fun (com.apollographql.cache.normalized.api/Record).com.apollographql.cache.normalized.api/receivedDate(kotlin/String): kotlin/Long? // com.apollographql.cache.normalized.api/receivedDate|receivedDate@com.apollographql.cache.normalized.api.Record(kotlin.String){}[0] final fun (com.apollographql.cache.normalized.api/Record).com.apollographql.cache.normalized.api/withDates(kotlin/String?, kotlin/String?): com.apollographql.cache.normalized.api/Record // com.apollographql.cache.normalized.api/withDates|withDates@com.apollographql.cache.normalized.api.Record(kotlin.String?;kotlin.String?){}[0] diff --git a/normalized-cache/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt b/normalized-cache/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt index 89155ea6..be51523a 100644 --- a/normalized-cache/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt +++ b/normalized-cache/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt @@ -21,10 +21,14 @@ import com.apollographql.apollo.interceptor.ApolloInterceptorChain import com.apollographql.apollo.mpp.currentTimeMillis import com.apollographql.apollo.network.http.HttpInfo import com.apollographql.cache.normalized.api.ApolloCacheHeaders +import com.apollographql.cache.normalized.api.CacheControlCacheResolver import com.apollographql.cache.normalized.api.CacheHeaders import com.apollographql.cache.normalized.api.CacheKey import com.apollographql.cache.normalized.api.CacheKeyGenerator +import com.apollographql.cache.normalized.api.CacheKeyGeneratorContext import com.apollographql.cache.normalized.api.CacheResolver +import com.apollographql.cache.normalized.api.ConnectionMetadataGenerator +import com.apollographql.cache.normalized.api.ConnectionRecordMerger import com.apollographql.cache.normalized.api.DefaultEmbeddedFieldsProvider import com.apollographql.cache.normalized.api.DefaultFieldKeyGenerator import com.apollographql.cache.normalized.api.DefaultMaxAgeProvider @@ -32,10 +36,15 @@ import com.apollographql.cache.normalized.api.DefaultRecordMerger import com.apollographql.cache.normalized.api.EmbeddedFieldsProvider import com.apollographql.cache.normalized.api.EmptyMetadataGenerator import com.apollographql.cache.normalized.api.FieldKeyGenerator +import com.apollographql.cache.normalized.api.FieldPolicyCacheResolver +import com.apollographql.cache.normalized.api.GlobalMaxAgeProvider +import com.apollographql.cache.normalized.api.MaxAge import com.apollographql.cache.normalized.api.MaxAgeProvider import com.apollographql.cache.normalized.api.MetadataGenerator import com.apollographql.cache.normalized.api.NormalizedCacheFactory import com.apollographql.cache.normalized.api.RecordMerger +import com.apollographql.cache.normalized.api.SchemaCoordinatesMaxAgeProvider +import com.apollographql.cache.normalized.api.TypePolicy import com.apollographql.cache.normalized.api.TypePolicyCacheKeyGenerator import com.apollographql.cache.normalized.internal.ApolloCacheInterceptor import com.apollographql.cache.normalized.internal.WatcherInterceptor @@ -67,7 +76,7 @@ fun ApolloClient.Builder.normalizedCache( normalizedCacheFactory: NormalizedCacheFactory, cacheKeyGenerator: CacheKeyGenerator = @Suppress("DEPRECATION") TypePolicyCacheKeyGenerator, metadataGenerator: MetadataGenerator = EmptyMetadataGenerator, - cacheResolver: CacheResolver = com.apollographql.cache.normalized.api.FieldPolicyCacheResolver(keyScope = CacheKey.Scope.TYPE), + cacheResolver: CacheResolver = FieldPolicyCacheResolver(keyScope = CacheKey.Scope.TYPE), recordMerger: RecordMerger = DefaultRecordMerger, fieldKeyGenerator: FieldKeyGenerator = DefaultFieldKeyGenerator, embeddedFieldsProvider: EmbeddedFieldsProvider = DefaultEmbeddedFieldsProvider, @@ -88,6 +97,58 @@ fun ApolloClient.Builder.normalizedCache( ) } +fun ApolloClient.Builder.normalizedCache( + normalizedCacheFactory: NormalizedCacheFactory, + typePolicies: Map, + connectionTypes: Set, + maxAges: Map, + defaultMaxAge: Duration, + keyScope: CacheKey.Scope, + writeToCacheAsynchronously: Boolean, +): ApolloClient.Builder { + val cacheKeyGenerator = if (typePolicies.isEmpty()) { + object : CacheKeyGenerator { + override fun cacheKeyForObject(obj: Map, context: CacheKeyGeneratorContext): CacheKey? { + return null + } + } + } else { + TypePolicyCacheKeyGenerator(typePolicies, keyScope) + } + val metadataGenerator = if (connectionTypes.isEmpty()) { + EmptyMetadataGenerator + } else { + ConnectionMetadataGenerator(connectionTypes) + } + val maxAgeProvider = if (maxAges.isEmpty()) { + GlobalMaxAgeProvider(defaultMaxAge) + } else { + SchemaCoordinatesMaxAgeProvider(maxAges, defaultMaxAge) + } + val cacheResolver = if (maxAges.isEmpty()) { + FieldPolicyCacheResolver(keyScope) + } else { + CacheControlCacheResolver( + maxAgeProvider = maxAgeProvider, + delegateResolver = FieldPolicyCacheResolver(keyScope), + ) + } + val recordMerger = if (connectionTypes.isEmpty()) { + DefaultRecordMerger + } else { + ConnectionRecordMerger + } + return normalizedCache( + normalizedCacheFactory = normalizedCacheFactory, + cacheKeyGenerator = cacheKeyGenerator, + metadataGenerator = metadataGenerator, + cacheResolver = cacheResolver, + recordMerger = recordMerger, + maxAgeProvider = maxAgeProvider, + writeToCacheAsynchronously = writeToCacheAsynchronously, + ) +} + @JvmName("-logCacheMisses") fun ApolloClient.Builder.logCacheMisses( log: (String) -> Unit = { println(it) }, diff --git a/samples/browser/app/src/jsMain/kotlin/com/example/browsersample/repository/Apollo.kt b/samples/browser/app/src/jsMain/kotlin/com/example/browsersample/repository/Apollo.kt index f852ee06..63298058 100644 --- a/samples/browser/app/src/jsMain/kotlin/com/example/browsersample/repository/Apollo.kt +++ b/samples/browser/app/src/jsMain/kotlin/com/example/browsersample/repository/Apollo.kt @@ -5,17 +5,12 @@ import com.apollographql.apollo.ApolloClient import com.apollographql.apollo.api.Optional import com.apollographql.cache.normalized.FetchPolicy import com.apollographql.cache.normalized.api.CacheKey -import com.apollographql.cache.normalized.api.ConnectionMetadataGenerator -import com.apollographql.cache.normalized.api.ConnectionRecordMerger -import com.apollographql.cache.normalized.api.TypePolicyCacheKeyGenerator import com.apollographql.cache.normalized.fetchPolicy import com.apollographql.cache.normalized.memory.MemoryCacheFactory -import com.apollographql.cache.normalized.normalizedCache import com.apollographql.cache.normalized.sql.SqlNormalizedCacheFactory import com.example.browsersample.BuildConfig import com.example.browsersample.graphql.RepositoryListQuery -import com.example.browsersample.graphql.cache.Cache -import com.example.browsersample.graphql.pagination.Pagination +import com.example.browsersample.graphql.cache.Cache.cache import org.w3c.dom.Worker private const val SERVER_URL = "https://api.github.com/graphql" @@ -35,26 +30,21 @@ val apolloClient: ApolloClient by lazy { val memoryThenSqlCache = memoryCache.chain(sqlCache) ApolloClient.Builder() - .serverUrl(SERVER_URL) + .serverUrl(SERVER_URL) - // Add headers for authentication - .addHttpHeader( - HEADER_AUTHORIZATION, - "$HEADER_AUTHORIZATION_BEARER ${BuildConfig.GITHUB_OAUTH_KEY}" - ) + // Add headers for authentication + .addHttpHeader( + HEADER_AUTHORIZATION, + "$HEADER_AUTHORIZATION_BEARER ${BuildConfig.GITHUB_OAUTH_KEY}" + ) - // Normalized cache - .normalizedCache( - normalizedCacheFactory = memoryThenSqlCache, - cacheKeyGenerator = TypePolicyCacheKeyGenerator( - typePolicies = Cache.typePolicies, - keyScope = CacheKey.Scope.SERVICE, - ), - metadataGenerator = ConnectionMetadataGenerator(Pagination.connectionTypes), - recordMerger = ConnectionRecordMerger - ) + // Normalized cache + .cache( + normalizedCacheFactory = memoryThenSqlCache, + keyScope = CacheKey.Scope.SERVICE, + ) - .build() + .build() } suspend fun fetchAndMergeNextPage() { @@ -65,5 +55,5 @@ suspend fun fetchAndMergeNextPage() { // 2. Fetch the next page from the network and store it in the cache val after = cacheResponse.data!!.organization!!.repositories.pageInfo.endCursor apolloClient.query(RepositoryListQuery(after = Optional.presentIfNotNull(after))) - .fetchPolicy(FetchPolicy.NetworkOnly).execute() + .fetchPolicy(FetchPolicy.NetworkOnly).execute() } diff --git a/samples/pagination/manual/app/build.gradle.kts b/samples/pagination/manual/app/build.gradle.kts index a00c970f..1af6f266 100644 --- a/samples/pagination/manual/app/build.gradle.kts +++ b/samples/pagination/manual/app/build.gradle.kts @@ -65,7 +65,7 @@ apollo { service("main") { packageName.set("com.example.apollokotlinpaginationsample.graphql") - plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:1.0.0-alpha.3") { + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:1.0.0-alpha.4-SNAPSHOT") { argument("packageName", packageName.get()) } @@ -88,7 +88,7 @@ dependencies { implementation("androidx.compose.material3:material3") implementation("com.apollographql.apollo:apollo-runtime") - implementation("com.apollographql.cache:normalized-cache-sqlite:1.0.0-alpha.3") + implementation("com.apollographql.cache:normalized-cache-sqlite:1.0.0-alpha.4-SNAPSHOT") debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-test-manifest") diff --git a/samples/pagination/manual/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt b/samples/pagination/manual/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt index 5a1ab3bc..004ea2cd 100644 --- a/samples/pagination/manual/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt +++ b/samples/pagination/manual/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt @@ -14,6 +14,7 @@ import com.example.apollokotlinpaginationsample.Application import com.example.apollokotlinpaginationsample.BuildConfig import com.example.apollokotlinpaginationsample.graphql.RepositoryListQuery import com.example.apollokotlinpaginationsample.graphql.cache.Cache +import com.example.apollokotlinpaginationsample.graphql.cache.Cache.cache private const val SERVER_URL = "https://api.github.com/graphql" @@ -35,12 +36,9 @@ val apolloClient: ApolloClient by lazy { ) // Normalized cache - .normalizedCache( + .cache( memoryThenSqlCache, - cacheKeyGenerator = TypePolicyCacheKeyGenerator( - typePolicies = Cache.typePolicies, - keyScope = CacheKey.Scope.SERVICE, - ), + keyScope = CacheKey.Scope.SERVICE, ) .build() diff --git a/samples/pagination/manual/settings.gradle.kts b/samples/pagination/manual/settings.gradle.kts index d81c4214..ac2ce959 100644 --- a/samples/pagination/manual/settings.gradle.kts +++ b/samples/pagination/manual/settings.gradle.kts @@ -1,5 +1,6 @@ pluginManagement { repositories { + mavenLocal() maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") } @@ -10,6 +11,7 @@ pluginManagement { } dependencyResolutionManagement { repositories { + mavenLocal() maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") } diff --git a/samples/pagination/pagination-support-with-jetpack-paging/app/build.gradle.kts b/samples/pagination/pagination-support-with-jetpack-paging/app/build.gradle.kts index c8e41fa6..aefc4e4b 100644 --- a/samples/pagination/pagination-support-with-jetpack-paging/app/build.gradle.kts +++ b/samples/pagination/pagination-support-with-jetpack-paging/app/build.gradle.kts @@ -65,7 +65,7 @@ apollo { service("main") { packageName.set("com.example.apollokotlinpaginationsample.graphql") - plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:1.0.0-alpha.3") { + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:1.0.0-alpha.4-SNAPSHOT") { argument("packageName", packageName.get()) } @@ -88,7 +88,7 @@ dependencies { implementation("androidx.compose.material3:material3") implementation("com.apollographql.apollo:apollo-runtime") - implementation("com.apollographql.cache:normalized-cache-sqlite:1.0.0-alpha.3") + implementation("com.apollographql.cache:normalized-cache-sqlite:1.0.0-alpha.4-SNAPSHOT") implementation("androidx.paging:paging-runtime-ktx:3.3.6") implementation("androidx.paging:paging-compose:3.3.6") diff --git a/samples/pagination/pagination-support-with-jetpack-paging/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt b/samples/pagination/pagination-support-with-jetpack-paging/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt index 89c2764d..a8afae9e 100644 --- a/samples/pagination/pagination-support-with-jetpack-paging/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt +++ b/samples/pagination/pagination-support-with-jetpack-paging/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt @@ -24,6 +24,7 @@ import com.example.apollokotlinpaginationsample.Application import com.example.apollokotlinpaginationsample.BuildConfig import com.example.apollokotlinpaginationsample.graphql.RepositoryListQuery import com.example.apollokotlinpaginationsample.graphql.cache.Cache +import com.example.apollokotlinpaginationsample.graphql.cache.Cache.cache import com.example.apollokotlinpaginationsample.graphql.pagination.Pagination import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.take @@ -49,14 +50,9 @@ val apolloClient: ApolloClient by lazy { ) // Normalized cache - .normalizedCache( + .cache( normalizedCacheFactory = memoryThenSqlCache, - cacheKeyGenerator = TypePolicyCacheKeyGenerator( - typePolicies = Cache.typePolicies, - keyScope = CacheKey.Scope.SERVICE, - ), - metadataGenerator = ConnectionMetadataGenerator(Pagination.connectionTypes), - recordMerger = ConnectionRecordMerger + keyScope = CacheKey.Scope.SERVICE, ) .build() diff --git a/samples/pagination/pagination-support-with-jetpack-paging/settings.gradle.kts b/samples/pagination/pagination-support-with-jetpack-paging/settings.gradle.kts index d81c4214..ac2ce959 100644 --- a/samples/pagination/pagination-support-with-jetpack-paging/settings.gradle.kts +++ b/samples/pagination/pagination-support-with-jetpack-paging/settings.gradle.kts @@ -1,5 +1,6 @@ pluginManagement { repositories { + mavenLocal() maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") } @@ -10,6 +11,7 @@ pluginManagement { } dependencyResolutionManagement { repositories { + mavenLocal() maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") } diff --git a/samples/pagination/pagination-support/app/build.gradle.kts b/samples/pagination/pagination-support/app/build.gradle.kts index a00c970f..1af6f266 100644 --- a/samples/pagination/pagination-support/app/build.gradle.kts +++ b/samples/pagination/pagination-support/app/build.gradle.kts @@ -65,7 +65,7 @@ apollo { service("main") { packageName.set("com.example.apollokotlinpaginationsample.graphql") - plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:1.0.0-alpha.3") { + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:1.0.0-alpha.4-SNAPSHOT") { argument("packageName", packageName.get()) } @@ -88,7 +88,7 @@ dependencies { implementation("androidx.compose.material3:material3") implementation("com.apollographql.apollo:apollo-runtime") - implementation("com.apollographql.cache:normalized-cache-sqlite:1.0.0-alpha.3") + implementation("com.apollographql.cache:normalized-cache-sqlite:1.0.0-alpha.4-SNAPSHOT") debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-test-manifest") diff --git a/samples/pagination/pagination-support/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt b/samples/pagination/pagination-support/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt index 2adbdb13..535bb0a8 100644 --- a/samples/pagination/pagination-support/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt +++ b/samples/pagination/pagination-support/app/src/main/kotlin/com/example/apollokotlinpaginationsample/repository/Apollo.kt @@ -15,6 +15,7 @@ import com.example.apollokotlinpaginationsample.Application import com.example.apollokotlinpaginationsample.BuildConfig import com.example.apollokotlinpaginationsample.graphql.RepositoryListQuery import com.example.apollokotlinpaginationsample.graphql.cache.Cache +import com.example.apollokotlinpaginationsample.graphql.cache.Cache.cache import com.example.apollokotlinpaginationsample.graphql.pagination.Pagination private const val SERVER_URL = "https://api.github.com/graphql" @@ -37,14 +38,9 @@ val apolloClient: ApolloClient by lazy { ) // Normalized cache - .normalizedCache( + .cache( normalizedCacheFactory = memoryThenSqlCache, - cacheKeyGenerator = TypePolicyCacheKeyGenerator( - typePolicies = Cache.typePolicies, - keyScope = CacheKey.Scope.SERVICE, - ), - metadataGenerator = ConnectionMetadataGenerator(Pagination.connectionTypes), - recordMerger = ConnectionRecordMerger + keyScope = CacheKey.Scope.SERVICE, ) .build() diff --git a/samples/pagination/pagination-support/settings.gradle.kts b/samples/pagination/pagination-support/settings.gradle.kts index d81c4214..ac2ce959 100644 --- a/samples/pagination/pagination-support/settings.gradle.kts +++ b/samples/pagination/pagination-support/settings.gradle.kts @@ -1,5 +1,6 @@ pluginManagement { repositories { + mavenLocal() maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") } @@ -10,6 +11,7 @@ pluginManagement { } dependencyResolutionManagement { repositories { + mavenLocal() maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") } diff --git a/tests/cache-control/src/commonTest/kotlin/ClientSideCacheControlTest.kt b/tests/cache-control/src/commonTest/kotlin/ClientSideCacheControlTest.kt index 3a64205a..e5712d05 100644 --- a/tests/cache-control/src/commonTest/kotlin/ClientSideCacheControlTest.kt +++ b/tests/cache-control/src/commonTest/kotlin/ClientSideCacheControlTest.kt @@ -20,6 +20,7 @@ import com.apollographql.cache.normalized.memory.MemoryCacheFactory import com.apollographql.cache.normalized.normalizedCache import com.apollographql.cache.normalized.sql.SqlNormalizedCacheFactory import com.apollographql.cache.normalized.testing.runTest +import declarative.cache.Cache.cache import programmatic.GetCompanyQuery import programmatic.GetUserAdminQuery import programmatic.GetUserEmailQuery @@ -188,15 +189,10 @@ class ClientSideCacheControlTest { } private fun declarativeMaxAge(normalizedCacheFactory: NormalizedCacheFactory) = runTest { - val maxAgeProvider = SchemaCoordinatesMaxAgeProvider( - declarative.cache.Cache.maxAges, - defaultMaxAge = 20.seconds, - ) - val client = ApolloClient.Builder() - .normalizedCache( + .cache( normalizedCacheFactory = normalizedCacheFactory, - cacheResolver = CacheControlCacheResolver(maxAgeProvider), + defaultMaxAge = 20.seconds, ) .serverUrl("unused") .build() diff --git a/tests/pagination/build.gradle.kts b/tests/pagination/build.gradle.kts index 3739b1b0..05d70b47 100644 --- a/tests/pagination/build.gradle.kts +++ b/tests/pagination/build.gradle.kts @@ -49,41 +49,76 @@ apollo { srcDir("src/commonMain/graphql/pagination/offsetBasedWithArray") @OptIn(ApolloExperimental::class) generateDataBuilders.set(true) + + @OptIn(ApolloExperimental::class) + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + argument("packageName", packageName.get()) + } } service("pagination.offsetBasedWithPage") { packageName.set("pagination.offsetBasedWithPage") srcDir("src/commonMain/graphql/pagination/offsetBasedWithPage") @OptIn(ApolloExperimental::class) generateDataBuilders.set(true) + + @OptIn(ApolloExperimental::class) + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + argument("packageName", packageName.get()) + } } service("pagination.offsetBasedWithPageAndInput") { packageName.set("pagination.offsetBasedWithPageAndInput") srcDir("src/commonMain/graphql/pagination/offsetBasedWithPageAndInput") @OptIn(ApolloExperimental::class) generateDataBuilders.set(true) + + @OptIn(ApolloExperimental::class) + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + argument("packageName", packageName.get()) + } } service("pagination.cursorBased") { packageName.set("pagination.cursorBased") srcDir("src/commonMain/graphql/pagination/cursorBased") @OptIn(ApolloExperimental::class) generateDataBuilders.set(true) + + @OptIn(ApolloExperimental::class) + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + argument("packageName", packageName.get()) + } } service("pagination.connection") { packageName.set("pagination.connection") srcDir("src/commonMain/graphql/pagination/connection") @OptIn(ApolloExperimental::class) generateDataBuilders.set(true) + + @OptIn(ApolloExperimental::class) + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + argument("packageName", packageName.get()) + } } service("pagination.connectionWithNodes") { packageName.set("pagination.connectionWithNodes") srcDir("src/commonMain/graphql/pagination/connectionWithNodes") @OptIn(ApolloExperimental::class) generateDataBuilders.set(true) + + @OptIn(ApolloExperimental::class) + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + argument("packageName", packageName.get()) + } } service("pagination.connectionProgrammatic") { packageName.set("pagination.connectionProgrammatic") srcDir("src/commonMain/graphql/pagination/connectionProgrammatic") @OptIn(ApolloExperimental::class) generateDataBuilders.set(true) + + @OptIn(ApolloExperimental::class) + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + argument("packageName", packageName.get()) + } } }