diff --git a/CHANGELOG.md b/CHANGELOG.md index b1db4029..091c4c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ # Next version (unreleased) -PUT_CHANGELOG_HERE +- Expiration support (see [the documentation](https://apollographql.github.io/apollo-kotlin-normalized-cache-incubating/expiration.html) for details) +- Compatibility with the IntelliJ plugin cache viewer (#42) # Version 0.0.3 _2024-09-20_ -PUT_CHANGELOG_HERE +Tweaks to the `ApolloResolver` API: `resolveField()` now takes a `ResolverContext` # Version 0.0.2 _2024-07-08_ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c4af0a0d..ccbf7f72 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] kotlin-plugin = "2.0.0" -android-plugin = "8.2.2" -apollo = "4.0.1" +android-plugin = "8.7.0" +apollo = "4.0.2-SNAPSHOT" okio = "3.9.0" atomicfu = "0.23.1" # Must be the same version as the one used by apollo-testing-support or native compilation will fail sqldelight = "2.0.1" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136..a4b76b95 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4413138..df97d72b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13..f5feea6d 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30db..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/normalized-cache-incubating/build.gradle.kts b/normalized-cache-incubating/build.gradle.kts index 8e1e8379..6f0a7a95 100644 --- a/normalized-cache-incubating/build.gradle.kts +++ b/normalized-cache-incubating/build.gradle.kts @@ -33,13 +33,18 @@ kotlin { @OptIn(ExperimentalKotlinGradlePluginApi::class) applyDefaultHierarchyTemplate { group("common") { - group("noWasm") { - group("concurrent") { - group("apple") - withJvm() - } + group("concurrent") { + group("apple") withJvm() } + group("jsCommon") { + group("js") { + withJs() + } + group("wasmJs") { + withWasmJs() + } + } } } diff --git a/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ApolloStore.kt b/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ApolloStore.kt index c2310683..901752ad 100644 --- a/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ApolloStore.kt +++ b/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ApolloStore.kt @@ -3,6 +3,7 @@ package com.apollographql.cache.normalized import com.apollographql.apollo.api.CustomScalarAdapters import com.apollographql.apollo.api.Fragment import com.apollographql.apollo.api.Operation +import com.apollographql.apollo.api.json.JsonNumber import com.apollographql.apollo.interceptor.ApolloInterceptor import com.apollographql.cache.normalized.api.CacheHeaders import com.apollographql.cache.normalized.api.CacheKey @@ -223,3 +224,39 @@ fun ApolloStore( * Interface that marks all interceptors added when configuring a `store()` on ApolloClient.Builder. */ internal interface ApolloStoreInterceptor : ApolloInterceptor + +internal fun ApolloStore.cacheDumpProvider(): () -> Map>>> { + return { + dump().map { (cacheClass, cacheRecords) -> + cacheClass.normalizedCacheName() to cacheRecords.mapValues { (_, record) -> + record.size to record.fields.mapValues { (_, value) -> + value.toExternal() + } + } + }.toMap() + } +} + +private fun Any?.toExternal(): Any? { + return when (this) { + null -> null + is String -> this + is Boolean -> this + is Int -> this + is Long -> this + is Double -> this + is JsonNumber -> this + is CacheKey -> this.serialize() + is List<*> -> { + map { it.toExternal() } + } + + is Map<*, *> -> { + mapValues { it.value.toExternal() } + } + + else -> error("Unsupported record value type: '$this'") + } +} + +internal expect fun KClass<*>.normalizedCacheName(): String diff --git a/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt b/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt index f4c8d534..8c0a3df1 100644 --- a/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt +++ b/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/ClientCacheExtensions.kt @@ -4,6 +4,7 @@ package com.apollographql.cache.normalized import com.apollographql.apollo.ApolloCall import com.apollographql.apollo.ApolloClient +import com.apollographql.apollo.CacheDumpProviderContext import com.apollographql.apollo.annotations.ApolloDeprecatedSince import com.apollographql.apollo.annotations.ApolloDeprecatedSince.Version.v4_0_0 import com.apollographql.apollo.api.ApolloRequest @@ -155,6 +156,7 @@ fun ApolloClient.Builder.store(store: ApolloStore, writeToCacheAsynchronously: B .addInterceptor(FetchPolicyRouterInterceptor) .addInterceptor(ApolloCacheInterceptor(store)) .writeToCacheAsynchronously(writeToCacheAsynchronously) + .addExecutionContext(CacheDumpProviderContext(store.cacheDumpProvider())) } @Deprecated(level = DeprecationLevel.ERROR, message = "Exceptions no longer throw", replaceWith = ReplaceWith("watch()")) diff --git a/normalized-cache-incubating/src/concurrentMain/kotlin/com/apollographql/cache/normalized/ApolloStore.concurrent.kt b/normalized-cache-incubating/src/concurrentMain/kotlin/com/apollographql/cache/normalized/ApolloStore.concurrent.kt new file mode 100644 index 00000000..23557e4e --- /dev/null +++ b/normalized-cache-incubating/src/concurrentMain/kotlin/com/apollographql/cache/normalized/ApolloStore.concurrent.kt @@ -0,0 +1,7 @@ +package com.apollographql.cache.normalized + +import kotlin.reflect.KClass + +internal actual fun KClass<*>.normalizedCacheName(): String { + return qualifiedName ?: toString() +} diff --git a/normalized-cache-incubating/src/jsCommonMain/kotlin/com/apollographql/cache/normalized/ApolloStore.jsCommon.kt b/normalized-cache-incubating/src/jsCommonMain/kotlin/com/apollographql/cache/normalized/ApolloStore.jsCommon.kt new file mode 100644 index 00000000..d69e43a5 --- /dev/null +++ b/normalized-cache-incubating/src/jsCommonMain/kotlin/com/apollographql/cache/normalized/ApolloStore.jsCommon.kt @@ -0,0 +1,8 @@ +package com.apollographql.cache.normalized + +import kotlin.reflect.KClass + +internal actual fun KClass<*>.normalizedCacheName(): String { + // qualifiedName is unsupported in JS + return simpleName ?: toString() +} diff --git a/settings.gradle.kts b/settings.gradle.kts index ebce4b5b..50b36b73 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,12 @@ pluginManagement { listOf(repositories, dependencyResolutionManagement.repositories).forEach { - it.mavenCentral() - it.google() + it.apply { + maven { + url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") + } + mavenCentral() + google() + } } } diff --git a/tests/build.gradle.kts b/tests/build.gradle.kts index 2eb05a51..2711613c 100644 --- a/tests/build.gradle.kts +++ b/tests/build.gradle.kts @@ -1,5 +1,8 @@ buildscript { repositories { + maven { + url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") + } mavenCentral() google() } diff --git a/tests/settings.gradle.kts b/tests/settings.gradle.kts index 7b7aa42d..270910de 100644 --- a/tests/settings.gradle.kts +++ b/tests/settings.gradle.kts @@ -3,6 +3,9 @@ includeBuild("../") pluginManagement { listOf(repositories, dependencyResolutionManagement.repositories).forEach { it.apply { + maven { + url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") + } mavenCentral() } }