diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index e11691d..eb0ccaa 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -83,3 +83,8 @@ jobs:
path: stream-android-core/build/reports/tests/testDebugUnitTest/index.html
- uses: GetStream/android-ci-actions/actions/setup-ruby@main
+
+ - name: Sonar
+ run: ./gradlew sonar
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c1cefed..bbb8209 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,9 +1,21 @@
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
}
+kotlin {
+ compilerOptions {
+ jvmTarget.set(JvmTarget.JVM_11)
+ freeCompilerArgs.addAll(
+ "-opt-in=io.getstream.android.core.annotations.StreamInternalApi",
+ "-XXLanguage:+PropertyParamAnnotationDefaultTargetMode"
+ )
+ }
+}
+
android {
namespace = "io.getstream.android.core"
compileSdk = 36
@@ -42,6 +54,7 @@ android {
dependencies {
implementation(project(":stream-android-core"))
+ implementation(project(":stream-android-core-annotations"))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
diff --git a/buildSrc/src/main/kotlin/io/getstream/core/Configuration.kt b/buildSrc/src/main/kotlin/io/getstream/core/Configuration.kt
index fee1e76..3f415bd 100644
--- a/buildSrc/src/main/kotlin/io/getstream/core/Configuration.kt
+++ b/buildSrc/src/main/kotlin/io/getstream/core/Configuration.kt
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * https://github.com/GetStream/stream-feeds-android/blob/main/LICENSE
+ * https://github.com/GetStream/stream-core-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/lint.xml b/lint.xml
index 2c7b502..82addf1 100644
--- a/lint.xml
+++ b/lint.xml
@@ -8,8 +8,7 @@
-
+
-
diff --git a/stream-android-core-annotations/src/main/java/io/getstream/android/core/annotations/StreamApiMarkers.kt b/stream-android-core-annotations/src/main/java/io/getstream/android/core/annotations/StreamApiMarkers.kt
index c64e6d8..3cc74f5 100644
--- a/stream-android-core-annotations/src/main/java/io/getstream/android/core/annotations/StreamApiMarkers.kt
+++ b/stream-android-core-annotations/src/main/java/io/getstream/android/core/annotations/StreamApiMarkers.kt
@@ -88,15 +88,9 @@ annotation class StreamInternalApi
annotation class StreamDelicateApi(val message: String)
/**
- * Marks APIs that are part of the **Stream Core SDK layer**.
- *
- * These APIs are primarily intended for **internal use within Stream SDKs** (e.g. video, chat, or
- * other verticals) and are not considered public surface APIs.
- *
- * While they may be accessible, external usage is **discouraged** because:
- * - Support will typically focus on higher-level, public APIs instead.
- * - A vertical can upgrade to a major version of Stream core that may no longer have or support
- * this api.
+ * Marks APIs that are part of the **Stream core SDK layer**. This API can be safely published and
+ * used by other Stream SDKs. They can also be propagated and exposed via public APIs of the product
+ * SDKs.
*/
@Target(
AnnotationTarget.CLASS,
@@ -106,10 +100,4 @@ annotation class StreamDelicateApi(val message: String)
AnnotationTarget.TYPEALIAS,
)
@Retention(AnnotationRetention.BINARY)
-@RequiresOptIn(
- message =
- "Stream Core SDK API – intended for use only within the Stream SDK core. " +
- "External usage is discouraged and may not be supported.",
- level = RequiresOptIn.Level.ERROR,
-)
-annotation class StreamCoreApi
+annotation class StreamPublishedApi
diff --git a/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/StreamIssueRegistry.kt b/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/StreamIssueRegistry.kt
index 1bcfc1b..ed45173 100644
--- a/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/StreamIssueRegistry.kt
+++ b/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/StreamIssueRegistry.kt
@@ -22,7 +22,7 @@ import com.android.tools.lint.detector.api.Issue
import io.getstream.android.core.lint.detectors.ExposeAsStateFlowDetector
import io.getstream.android.core.lint.detectors.KeepInstanceDetector
import io.getstream.android.core.lint.detectors.MustBeInternalDetector
-import io.getstream.android.core.lint.detectors.StreamCoreApiDetector
+import io.getstream.android.core.lint.detectors.StreamApiExplicitMarkerDetector
import io.getstream.android.core.lint.detectors.SuspendRunCatchingDetector
/** The stream lint rules registry. */
@@ -34,7 +34,7 @@ class StreamIssueRegistry : IssueRegistry() {
KeepInstanceDetector.ISSUE,
SuspendRunCatchingDetector.ISSUE,
ExposeAsStateFlowDetector.ISSUE,
- StreamCoreApiDetector.ISSUE,
+ StreamApiExplicitMarkerDetector.ISSUE,
)
override val vendor =
diff --git a/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/detectors/StreamApiExplicitMarkerDetector.kt b/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/detectors/StreamApiExplicitMarkerDetector.kt
new file mode 100644
index 0000000..aab2e20
--- /dev/null
+++ b/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/detectors/StreamApiExplicitMarkerDetector.kt
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2014-2025 Stream.io Inc. All rights reserved.
+ *
+ * Licensed under the Stream License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/GetStream/stream-core-android/blob/main/LICENSE
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.getstream.android.core.lint.detectors
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.*
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.uast.*
+
+class StreamApiExplicitMarkerDetector : Detector(), Detector.UastScanner {
+
+ override fun getApplicableUastTypes() =
+ listOf(UClass::class.java, UMethod::class.java, UField::class.java, UFile::class.java)
+
+ override fun createUastHandler(context: JavaContext) =
+ object : UElementHandler() {
+ override fun visitClass(node: UClass) {
+ val uFile = node.getContainingUFileOrNull() ?: return
+ if (!context.packageMatchesConfig(uFile.packageName)) return
+ checkUAnnotated(context, node, node.sourcePsi as? KtDeclaration)
+ }
+
+ override fun visitMethod(node: UMethod) {
+ val uFile = node.getContainingUFileOrNull() ?: return
+ if (!context.packageMatchesConfig(uFile.packageName)) return
+ checkUAnnotated(context, node, node.sourcePsi as? KtNamedFunction)
+ }
+
+ override fun visitField(node: UField) {
+ val uFile = node.getContainingUFileOrNull() ?: return
+ if (!context.packageMatchesConfig(uFile.packageName)) return
+ checkUAnnotated(context, node, node.sourcePsi as? KtProperty)
+ }
+
+ override fun visitFile(node: UFile) {
+ val ktFile = node.sourcePsi as? KtFile ?: return
+ val pkg = ktFile.packageFqName.asString()
+ if (!context.packageMatchesConfig(pkg)) return
+ ktFile.declarations.filterIsInstance().forEach { alias ->
+ checkTypeAlias(context, alias)
+ }
+ }
+ }
+
+ private fun checkUAnnotated(context: JavaContext, u: UElement, kt: KtDeclaration?) {
+ kt ?: return
+ if (!kt.isTopLevelPublic()) return
+ val annotated = (u as? UAnnotated)?.hasAnyAnnotation(MARKERS) ?: false
+ if (annotated) return
+ reportWithDualFix(context, u, kt)
+ }
+
+ private fun checkTypeAlias(context: JavaContext, alias: KtTypeAlias) {
+ if (!alias.isTopLevelPublic()) return
+ val annotated = alias.hasAnyAnnotationPsi(MARKERS_SIMPLE)
+ if (annotated) return
+ reportWithDualFix(context, alias, alias)
+ }
+
+ private fun reportWithDualFix(context: JavaContext, node: KtTypeAlias, decl: KtDeclaration) {
+ val loc = context.getLocation(decl)
+ val fixPublished =
+ LintFix.create()
+ .name("Annotate with @$PUBLISHED_SIMPLE")
+ .replace()
+ .range(loc)
+ .pattern("^")
+ .with("@$PUBLISHED_FQ\n")
+ .reformat(true)
+ .shortenNames()
+ .autoFix()
+ .build()
+ val fixInternal =
+ LintFix.create()
+ .name("Annotate with @$INTERNAL_SIMPLE")
+ .replace()
+ .range(loc)
+ .pattern("^")
+ .with("@$INTERNAL_FQ\n")
+ .reformat(true)
+ .shortenNames()
+ .autoFix()
+ .build()
+
+ context.report(
+ ISSUE,
+ node,
+ loc,
+ "Public API must be explicitly marked with @$PUBLISHED_SIMPLE or @$INTERNAL_SIMPLE.",
+ LintFix.create().group(fixPublished, fixInternal),
+ )
+ }
+
+ private fun reportWithDualFix(context: JavaContext, node: UElement, decl: KtDeclaration) {
+ val loc = context.getLocation(decl)
+ val fixPublished =
+ LintFix.create()
+ .name("Annotate with @$PUBLISHED_SIMPLE")
+ .replace()
+ .range(loc)
+ .pattern("^")
+ .with("@$PUBLISHED_FQ\n")
+ .reformat(true)
+ .shortenNames()
+ .autoFix()
+ .build()
+ val fixInternal =
+ LintFix.create()
+ .name("Annotate with @$INTERNAL_SIMPLE")
+ .replace()
+ .range(loc)
+ .pattern("^")
+ .with("@$INTERNAL_FQ\n")
+ .reformat(true)
+ .shortenNames()
+ .autoFix()
+ .build()
+
+ context.report(
+ ISSUE,
+ node,
+ loc,
+ "Public API must be explicitly marked with @$PUBLISHED_SIMPLE or @$INTERNAL_SIMPLE.",
+ LintFix.create().group(fixPublished, fixInternal),
+ )
+ }
+
+ // ----- package filtering helpers -----
+
+ private fun JavaContext.packageMatchesConfig(pkg: String): Boolean {
+ val patterns = configuredPackageGlobs()
+
+ // Default if not configured → only io.getstream.android.core.*
+ val effectivePatterns = patterns.ifEmpty { listOf("io.getstream.android.core.api") }
+
+ val included = effectivePatterns.any { pkgMatchesGlob(pkg, it) }
+ val excluded = packageMatchesExcludeConfig(pkg)
+ return included && !excluded
+ }
+
+ private fun JavaContext.packageMatchesExcludeConfig(pkg: String): Boolean {
+ val raw = configuration.getOption(ISSUE, OPTION_PACKAGES_EXCLUDE.name, "")?.trim().orEmpty()
+ if (raw.isEmpty()) return false
+ val patterns = raw.split(',').map { it.trim() }.filter { it.isNotEmpty() }
+ return patterns.any { pkgMatchesGlob(pkg, it) }
+ }
+
+ private fun JavaContext.configuredPackageGlobs(): List {
+ val raw = configuration.getOption(ISSUE, OPTION_PACKAGES.name, "")?.trim().orEmpty()
+ if (raw.isEmpty()) return emptyList()
+ return raw.split(',').map { it.trim() }.filter { it.isNotEmpty() }
+ }
+
+ /** Simple glob matcher: `*` → `.*`, `?` → `.`, dot escaped; anchored. */
+ private fun pkgMatchesGlob(pkg: String, glob: String): Boolean = globToRegex(glob).matches(pkg)
+
+ private fun globToRegex(glob: String): Regex {
+ val sb = StringBuilder("^")
+ for (ch in glob) {
+ when (ch) {
+ '*' -> sb.append(".*")
+ '?' -> sb.append('.')
+ '.' -> sb.append("\\.")
+ else -> sb.append(Regex.escape(ch.toString()))
+ }
+ }
+ sb.append('$')
+ return sb.toString().toRegex()
+ }
+
+ // ----- misc helpers -----
+
+ private fun UAnnotated.hasAnyAnnotation(qns: Set) =
+ qns.any { findAnnotation(it) != null || findAnnotation(it.substringAfterLast('.')) != null }
+
+ private fun KtAnnotated.hasAnyAnnotationPsi(simpleNames: Set): Boolean =
+ annotationEntries.any { entry ->
+ entry.shortName?.asString() in simpleNames ||
+ entry.typeReference?.text in simpleNames // handles rare fully-qualified usage
+ }
+
+ private fun UElement.getContainingUFileOrNull(): UFile? {
+ var cur: UElement? = this
+ while (cur != null) {
+ if (cur is UFile) return cur
+ cur = cur.uastParent
+ }
+ return null
+ }
+
+ private fun KtDeclaration.isTopLevelPublic(): Boolean {
+ if (parent !is KtFile) return false
+ val mods = modifierList
+ val isPublic =
+ mods?.hasModifier(KtTokens.PUBLIC_KEYWORD) == true ||
+ !(mods?.hasModifier(KtTokens.PRIVATE_KEYWORD) == true ||
+ mods?.hasModifier(KtTokens.PROTECTED_KEYWORD) == true ||
+ mods?.hasModifier(KtTokens.INTERNAL_KEYWORD) == true)
+ return isPublic
+ }
+
+ companion object {
+ private const val PUBLISHED_FQ = "io.getstream.android.core.annotations.StreamPublishedApi"
+ private const val PUBLISHED_SIMPLE = "StreamPublishedApi"
+ private const val INTERNAL_FQ = "io.getstream.android.core.annotations.StreamInternalApi"
+ private const val INTERNAL_SIMPLE = "StreamInternalApi"
+ private val MARKERS = setOf(PUBLISHED_FQ, INTERNAL_FQ)
+ private val MARKERS_SIMPLE = setOf(PUBLISHED_SIMPLE, INTERNAL_SIMPLE)
+
+ private val OPTION_PACKAGES =
+ StringOption(
+ name = "packages",
+ description = "Comma-separated package **glob** patterns where the rule applies.",
+ explanation =
+ """
+ Supports wildcards: '*' (any sequence) and '?' (single char).
+ Examples:
+ - 'io.getstream.android.core.api'
+ - 'io.getstream.android.core.*.api'
+ - 'io.getstream.android.*'
+ """
+ .trimIndent(),
+ )
+
+ private val OPTION_PACKAGES_EXCLUDE =
+ StringOption(
+ name = "exclude_packages",
+ description = "Comma-separated package **glob** patterns to exclude from the rule.",
+ explanation =
+ """
+ Same glob syntax as 'packages'. Evaluated after includes.
+ """
+ .trimIndent(),
+ )
+
+ private val IMPLEMENTATION =
+ Implementation(StreamApiExplicitMarkerDetector::class.java, Scope.JAVA_FILE_SCOPE)
+
+ @JvmField
+ val ISSUE: Issue =
+ Issue.create(
+ "StreamApiExplicitMarkerMissing",
+ "Public API must be explicitly marked",
+ """
+ To prevent accidental exposure, all top-level public declarations must be explicitly \
+ marked as @StreamPublishedApi (allowed to leak) or @StreamInternalApi (not allowed to leak).
+ """
+ .trimIndent(),
+ Category.CORRECTNESS,
+ 7,
+ Severity.ERROR,
+ IMPLEMENTATION,
+ )
+ .setOptions(listOf(OPTION_PACKAGES, OPTION_PACKAGES_EXCLUDE))
+ }
+}
diff --git a/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/detectors/StreamCoreApiDetector.kt b/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/detectors/StreamCoreApiDetector.kt
deleted file mode 100644
index e8f94f3..0000000
--- a/stream-android-core-lint/src/main/java/io/getstream/android/core/lint/detectors/StreamCoreApiDetector.kt
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (c) 2014-2025 Stream.io Inc. All rights reserved.
- *
- * Licensed under the Stream License;
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://github.com/GetStream/stream-core-android/blob/main/LICENSE
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package io.getstream.android.core.lint.detectors
-
-import com.android.tools.lint.client.api.UElementHandler
-import com.android.tools.lint.detector.api.Category
-import com.android.tools.lint.detector.api.Detector
-import com.android.tools.lint.detector.api.Implementation
-import com.android.tools.lint.detector.api.Issue
-import com.android.tools.lint.detector.api.JavaContext
-import com.android.tools.lint.detector.api.LintFix
-import com.android.tools.lint.detector.api.Scope
-import com.android.tools.lint.detector.api.Severity
-import com.android.tools.lint.detector.api.StringOption
-import com.android.tools.lint.detector.api.TextFormat
-import kotlin.text.iterator
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtClass
-import org.jetbrains.kotlin.psi.KtClassOrObject
-import org.jetbrains.kotlin.psi.KtNamedFunction
-import org.jetbrains.kotlin.psi.KtObjectDeclaration
-import org.jetbrains.kotlin.psi.KtProperty
-import org.jetbrains.uast.UAnnotated
-import org.jetbrains.uast.UClass
-import org.jetbrains.uast.UElement
-import org.jetbrains.uast.UField
-import org.jetbrains.uast.UFile
-import org.jetbrains.uast.UMethod
-
-/**
- * Flags any **top-level public** declaration in configured packages that is **not annotated**
- * with @StreamCoreApi.
- *
- * Config:
- */
-class StreamCoreApiDetector : Detector(), Detector.UastScanner {
- override fun getApplicableUastTypes(): List> =
- listOf(UClass::class.java, UMethod::class.java, UField::class.java)
-
- override fun createUastHandler(context: JavaContext): UElementHandler =
- object : UElementHandler() {
- override fun visitClass(node: UClass) {
- // Only top-level declarations
- val uFile = node.uastParent as? UFile ?: return
- if (!context.packageMatchesConfig(uFile.packageName)) return
-
- val kt = node.sourcePsi as? KtClassOrObject ?: return
- if (!kt.isTopLevel()) return
- if (!kt.isPublicTopLevel()) return
- if (node.isAnnotatedWithCoreApi()) return
-
- reportMissingCoreApi(context, node, kt, declKeyword(kt))
- }
-
- override fun visitMethod(node: UMethod) {
- val uFile = node.getContainingUFileOrNull() ?: return
- if (!context.packageMatchesConfig(uFile.packageName)) return
-
- val kt = node.sourcePsi as? KtNamedFunction ?: return
- if (!kt.isTopLevel) return
- if (!kt.isPublicTopLevel()) return
- if ((node as UAnnotated).isAnnotatedWithCoreApi()) return
-
- reportMissingCoreApi(context, node, kt, "fun")
- }
-
- override fun visitField(node: UField) {
- val uFile = node.getContainingUFileOrNull() ?: return
- if (!context.packageMatchesConfig(uFile.packageName)) return
-
- val kt = node.sourcePsi as? KtProperty ?: return
- if (!kt.isTopLevel) return
- if (!kt.isPublicTopLevel()) return
- if ((node as UAnnotated).isAnnotatedWithCoreApi()) return
-
- val keyword = if (kt.isVar) "var" else "val"
- reportMissingCoreApi(context, node, kt, keyword)
- }
- }
-
- // ----- Reporting & Fix -----
-
- private fun reportMissingCoreApi(
- context: JavaContext,
- node: UElement,
- psiDecl: org.jetbrains.kotlin.psi.KtDeclaration,
- declKeyword: String,
- ) {
- val explanation = ISSUE.getExplanation(TextFormat.TEXT)
- val declLocation = context.getLocation(psiDecl)
-
- // Insert the FQ annotation and let Lint shorten the import automatically.
- val fix =
- LintFix.create()
- .name("Annotate with @StreamCoreApi")
- .replace()
- .range(declLocation)
- // Prepend the annotation at the very start of the declaration text
- .pattern("^")
- .with("@$CORE_API_FQ\n")
- .reformat(true)
- .shortenNames()
- .autoFix()
- .build()
-
- context.report(ISSUE, node, declLocation, explanation, fix)
- }
-
- // ----- Helpers -----
-
- private fun JavaContext.packageMatchesConfig(pkg: String): Boolean {
- val patterns = configuredPackageGlobs()
- if (patterns.isEmpty()) return false
- val included = patterns.any { pkgMatchesGlob(pkg, it) }
- val excluded = packageMatchesExcludeConfig(pkg)
- return included && !excluded
- }
-
- private fun JavaContext.packageMatchesExcludeConfig(pkg: String): Boolean {
- val raw = configuration.getOption(ISSUE, OPTION_PACKAGES_EXCLUDE.name, "")?.trim().orEmpty()
- if (raw.isEmpty()) return false
- val patterns = raw.split(',').map { it.trim() }.filter { it.isNotEmpty() }
- if (patterns.isEmpty()) return false
- return patterns.any { pkgMatchesGlob(pkg, it) }
- }
-
- private fun JavaContext.configuredPackageGlobs(): List {
- val raw = configuration.getOption(ISSUE, OPTION_PACKAGES.name, "")?.trim().orEmpty()
- if (raw.isEmpty()) return emptyList()
- return raw.split(',').map { it.trim() }.filter { it.isNotEmpty() }
- }
-
- /** Simple glob matcher: `*` → `.*`, `?` → `.`, dot is escaped; anchored. */
- private fun pkgMatchesGlob(pkg: String, glob: String): Boolean = globToRegex(glob).matches(pkg)
-
- private fun globToRegex(glob: String): Regex {
- val sb = StringBuilder("^")
- for (ch in glob) {
- when (ch) {
- '*' -> sb.append(".*")
- '?' -> sb.append('.')
- '.' -> sb.append("\\.")
- else -> sb.append(Regex.escape(ch.toString()))
- }
- }
- sb.append('$')
- return sb.toString().toRegex()
- }
-
- private fun UAnnotated.isAnnotatedWithCoreApi(): Boolean =
- findAnnotation(CORE_API_FQ) != null || findAnnotation(CORE_API_SIMPLE) != null
-
- private fun UMethod.getContainingUFileOrNull(): UFile? {
- var cur: UElement? = this
- while (cur != null) {
- if (cur is UFile) return cur
- cur = cur.uastParent
- }
- return null
- }
-
- private fun UField.getContainingUFileOrNull(): UFile? {
- var cur: UElement? = this
- while (cur != null) {
- if (cur is UFile) return cur
- cur = cur.uastParent
- }
- return null
- }
-
- private fun KtClassOrObject.isTopLevel(): Boolean =
- this.parent is org.jetbrains.kotlin.psi.KtFile
-
- private fun org.jetbrains.kotlin.psi.KtDeclaration.isPublicTopLevel(): Boolean {
- // top-level: public if no visibility modifier or explicit `public`
- val isPublic =
- hasModifier(KtTokens.PUBLIC_KEYWORD) ||
- (!hasModifier(KtTokens.INTERNAL_KEYWORD) &&
- !hasModifier(KtTokens.PRIVATE_KEYWORD) &&
- !hasModifier(KtTokens.PROTECTED_KEYWORD))
- return isPublic
- }
-
- private fun declKeyword(kt: KtClassOrObject): String =
- when (kt) {
- is KtClass ->
- when {
- kt.isInterface() -> "interface"
- kt.isEnum() -> "enum class"
- else -> "class"
- }
-
- is KtObjectDeclaration -> "object"
- else -> "class"
- }
-
- companion object {
- private const val CORE_API_FQ = "io.getstream.android.core.annotations.StreamCoreApi"
- private const val CORE_API_SIMPLE = "StreamCoreApi"
-
- private val IMPLEMENTATION =
- Implementation(StreamCoreApiDetector::class.java, Scope.JAVA_FILE_SCOPE)
-
- private val OPTION_PACKAGES =
- StringOption(
- name = "packages",
- description =
- "Comma-separated package **glob** patterns where top-level public APIs must be annotated with @StreamCoreApi.",
- explanation =
- """
- Supports wildcards: '*' (any sequence) and '?' (single char).
- Examples:
- - 'io.getstream.android.core.api'
- - 'io.getstream.android.core.*.api'
- - 'io.getstream.android.core.api*'
- """
- .trimIndent(),
- )
-
- private val OPTION_PACKAGES_EXCLUDE =
- StringOption(
- name = "exclude_packages",
- description =
- "Comma-separated package **glob** patterns where top-level public APIs are excluded from the check.",
- explanation =
- """
- Supports wildcards: '*' (any sequence) and '?' (single char).
- Examples:
- - 'io.getstream.android.core.api'
- - 'io.getstream.android.core.*.api'
- - 'io.getstream.android.core.api*'
- """
- .trimIndent(),
- )
-
- @JvmField
- val ISSUE: Issue =
- Issue.create(
- id = "StreamCoreApiMissing",
- briefDescription = "Missing @StreamCoreApi on public API",
- explanation =
- """
- Top-level public declarations in configured packages must be annotated \
- with @StreamCoreApi to indicate they are part of the Stream Core API surface.
- """
- .trimIndent(),
- category = Category.CORRECTNESS,
- priority = 7,
- severity = Severity.ERROR,
- implementation = IMPLEMENTATION,
- )
- .setOptions(listOf(OPTION_PACKAGES, OPTION_PACKAGES_EXCLUDE))
- }
-}
diff --git a/stream-android-core/build.gradle.kts b/stream-android-core/build.gradle.kts
index 08d945d..83bffe4 100644
--- a/stream-android-core/build.gradle.kts
+++ b/stream-android-core/build.gradle.kts
@@ -1,5 +1,8 @@
+@file:OptIn(ExperimentalAbiValidation::class)
+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import io.getstream.core.Configuration
+import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation
plugins {
alias(libs.plugins.android.library)
@@ -19,10 +22,12 @@ rootProject.extra.apply {
apply(from = "${rootDir}/scripts/publish-module.gradle")
kotlin {
+ explicitApi()
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
freeCompilerArgs.addAll(
- "-opt-in=io.getstream.android.core.annotations.StreamCoreApi", "-XXLanguage:+PropertyParamAnnotationDefaultTargetMode"
+ "-opt-in=io.getstream.android.core.annotations.StreamInternalApi",
+ "-XXLanguage:+PropertyParamAnnotationDefaultTargetMode"
)
}
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/StreamClient.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/StreamClient.kt
index 21f1e66..d4d2868 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/StreamClient.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/StreamClient.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.authentication.StreamTokenManager
import io.getstream.android.core.api.authentication.StreamTokenProvider
import io.getstream.android.core.api.http.StreamOkHttpInterceptors
@@ -96,8 +96,8 @@ import kotlinx.coroutines.flow.StateFlow
* client.disconnect()
* ```
*/
-@StreamCoreApi
-interface StreamClient {
+@StreamInternalApi
+public interface StreamClient {
/**
* Read-only, hot state holder for this client.
*
@@ -105,7 +105,7 @@ interface StreamClient {
* - Emits connection status changes (e.g., connecting/connected/disconnected).
* - Hot & conflated: new collectors receive the latest value immediately.
*/
- val connectionState: StateFlow
+ public val connectionState: StateFlow
/**
* Establishes a connection for the current user.
@@ -117,7 +117,7 @@ interface StreamClient {
* **Cancellation**
* - Throws [kotlinx.coroutines.CancellationException] if the awaiting coroutine is cancelled.
*/
- suspend fun connect(): Result
+ public suspend fun connect(): Result
/**
* Terminates the active connection and releases related resources.
@@ -129,14 +129,14 @@ interface StreamClient {
* **Cancellation**
* - Throws [kotlinx.coroutines.CancellationException] if the awaiting coroutine is cancelled.
*/
- suspend fun disconnect(): Result
+ public suspend fun disconnect(): Result
/**
* Subscribes to client events and state
*
* @param listener The listener to subscribe.
*/
- fun subscribe(listener: StreamClientListener): Result
+ public fun subscribe(listener: StreamClientListener): Result
}
/**
@@ -199,8 +199,8 @@ interface StreamClient {
* @param healthMonitor The health monitor.
* @param batcher The WebSocket event batcher.
*/
-@StreamCoreApi
-fun StreamClient(
+@StreamInternalApi
+public fun StreamClient(
// Client config
apiKey: StreamApiKey,
userId: StreamUserId,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenManager.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenManager.kt
index d872b3e..6e7506a 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenManager.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenManager.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.authentication
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.model.value.StreamToken
import io.getstream.android.core.api.model.value.StreamUserId
import io.getstream.android.core.api.processing.StreamSingleFlightProcessor
@@ -49,15 +49,15 @@ import kotlinx.coroutines.flow.StateFlow
* tokenManager.token.value // null
* ```
*/
-@StreamCoreApi
-interface StreamTokenManager {
+@StreamInternalApi
+public interface StreamTokenManager {
/**
* A hot stream of the current authentication token.
*
* Emits `null` when there is no token (e.g., before the first load or after [invalidate] is
* called) and updates with each successful set or refresh.
*/
- val token: StateFlow
+ public val token: StateFlow
/**
* Registers the provider used to load tokens on demand.
@@ -69,7 +69,7 @@ interface StreamTokenManager {
* @return [Result.success] on success, or [Result.failure] if the provider cannot be installed
* in the current state.
*/
- fun setProvider(provider: StreamTokenProvider): Result
+ public fun setProvider(provider: StreamTokenProvider): Result
/**
* Sets the current token explicitly.
@@ -81,7 +81,7 @@ interface StreamTokenManager {
* @return [Result.success] on success, or [Result.failure] if the token is rejected by the
* implementation (e.g., invalid format).
*/
- fun setToken(token: StreamToken): Result
+ public fun setToken(token: StreamToken): Result
/**
* Invalidates and clears the current token.
@@ -92,7 +92,7 @@ interface StreamTokenManager {
* @return [Result.success] on success, or [Result.failure] if the token cannot be invalidated
* in the current state.
*/
- fun invalidate(): Result
+ public fun invalidate(): Result
/**
* Ensures that a valid token is available.
@@ -103,14 +103,14 @@ interface StreamTokenManager {
* @return [Result.success] containing the token, or [Result.failure] if no token is available
* and fetching failed.
*/
- suspend fun loadIfAbsent(): Result
+ public suspend fun loadIfAbsent(): Result
/**
* Refreshes the current token from the provider.
*
* @return [Result.success] containing the token, or [Result.failure] if fetching failed.
*/
- suspend fun refresh(): Result
+ public suspend fun refresh(): Result
}
/**
@@ -121,8 +121,8 @@ interface StreamTokenManager {
* @param singleFlight The single-flight processor used to coordinate concurrent requests.
* @return A new [StreamTokenManager] instance.
*/
-@StreamCoreApi
-fun StreamTokenManager(
+@StreamInternalApi
+public fun StreamTokenManager(
userId: StreamUserId,
tokenProvider: StreamTokenProvider,
singleFlight: StreamSingleFlightProcessor,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenProvider.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenProvider.kt
index 1530459..85633b2 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenProvider.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/authentication/StreamTokenProvider.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.authentication
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamPublishedApi
import io.getstream.android.core.api.model.value.StreamToken
import io.getstream.android.core.api.model.value.StreamUserId
@@ -52,8 +52,8 @@ import io.getstream.android.core.api.model.value.StreamUserId
* - Token creation/rotation must happen on your server.
* - Prefer short expirations and refresh on demand.
*/
-@StreamCoreApi
-fun interface StreamTokenProvider {
+@StreamPublishedApi
+public fun interface StreamTokenProvider {
/**
* Returns a JWT that authenticates the given [userId].
*
@@ -67,5 +67,5 @@ fun interface StreamTokenProvider {
* @throws Exception If the token cannot be obtained (network error, server error, invalid user,
* etc.).
*/
- suspend fun loadToken(userId: StreamUserId): StreamToken
+ public suspend fun loadToken(userId: StreamUserId): StreamToken
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/http/StreamOkHttpInterceptors.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/http/StreamOkHttpInterceptors.kt
index d9cdefd..0e99d6b 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/http/StreamOkHttpInterceptors.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/http/StreamOkHttpInterceptors.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.http
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.authentication.StreamTokenManager
import io.getstream.android.core.api.model.value.StreamApiKey
import io.getstream.android.core.api.model.value.StreamHttpClientInfoHeader
@@ -28,8 +28,6 @@ import io.getstream.android.core.internal.http.interceptor.StreamConnectionIdInt
import io.getstream.android.core.internal.http.interceptor.StreamEndpointErrorInterceptor
import okhttp3.Interceptor
-// TODO: Think about better approach
-
/**
* Provides a set of OkHttp interceptors for use with the Stream SDKs.
*
@@ -37,8 +35,8 @@ import okhttp3.Interceptor
* @see [StreamConnectionIdInterceptor]
* @see [StreamApiKeyInterceptor]
*/
-@StreamCoreApi
-object StreamOkHttpInterceptors {
+@StreamInternalApi
+public object StreamOkHttpInterceptors {
/**
* Creates an OkHttp interceptor that adds authentication headers and retries on token errors.
*
@@ -47,7 +45,7 @@ object StreamOkHttpInterceptors {
* @param jsonParser JSON parser used to decode error payloads when requests fail.
* @return An OkHttp interceptor.
*/
- fun auth(
+ public fun auth(
authType: String,
tokenManager: StreamTokenManager,
jsonParser: StreamJsonSerialization,
@@ -59,7 +57,7 @@ object StreamOkHttpInterceptors {
* @param connectionIdHolder The holder that provides the connection ID.
* @return An OkHttp interceptor.
*/
- fun connectionId(connectionIdHolder: StreamConnectionIdHolder): Interceptor =
+ public fun connectionId(connectionIdHolder: StreamConnectionIdHolder): Interceptor =
StreamConnectionIdInterceptor(connectionIdHolder)
/**
@@ -68,7 +66,7 @@ object StreamOkHttpInterceptors {
* @param clientInfoHeader The client info header to add.
* @return An OkHttp interceptor.
*/
- fun clientInfo(clientInfoHeader: StreamHttpClientInfoHeader): Interceptor =
+ public fun clientInfo(clientInfoHeader: StreamHttpClientInfoHeader): Interceptor =
StreamClientInfoInterceptor(clientInfoHeader)
/**
@@ -78,7 +76,7 @@ object StreamOkHttpInterceptors {
* @param apiKey The API key to add.
* @return An OkHttp interceptor.
*/
- fun apiKey(apiKey: StreamApiKey): Interceptor = StreamApiKeyInterceptor(apiKey)
+ public fun apiKey(apiKey: StreamApiKey): Interceptor = StreamApiKeyInterceptor(apiKey)
/**
* Creates an OkHttp interceptor that parses and throws
@@ -87,6 +85,6 @@ object StreamOkHttpInterceptors {
* @param jsonParser JSON parser used to decode error payloads when requests fail.
* @return An OkHttp interceptor.
*/
- fun error(jsonParser: StreamJsonSerialization): Interceptor =
+ public fun error(jsonParser: StreamJsonSerialization): Interceptor =
StreamEndpointErrorInterceptor(jsonParser)
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLogger.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLogger.kt
index 17c6e03..a363515 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLogger.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLogger.kt
@@ -15,40 +15,40 @@
*/
package io.getstream.android.core.api.log
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
/**
* Defines a logging contract for the Stream SDK.
*
* Implementations of this interface provide a way to log messages and exceptions at different
* severity levels. By default, convenience functions are provided for each log level (e.g., [d],
- * [e], [i], [w], [v], [wtf]).
+ * [e], [i], [w], [v]).
*
* @see StreamLoggerProvider for the global logger accessor.
*/
-@StreamCoreApi
-interface StreamLogger {
+@StreamInternalApi
+public interface StreamLogger {
/**
* Represents the severity of a log message.
*
* @property level The integer value of the severity, where higher numbers represent more severe
* log levels.
*/
- sealed class LogLevel(val level: Int) {
+ public sealed class LogLevel(public val level: Int) {
/** Verbose log messages, typically for detailed debugging. */
- object Verbose : LogLevel(1)
+ public object Verbose : LogLevel(1)
/** Debug log messages, used for general debugging. */
- object Debug : LogLevel(2)
+ public object Debug : LogLevel(2)
/** Informational log messages, representing normal operation. */
- object Info : LogLevel(3)
+ public object Info : LogLevel(3)
/** Warning log messages, representing non-fatal issues. */
- object Warning : LogLevel(4)
+ public object Warning : LogLevel(4)
/** Error log messages, representing recoverable failures. */
- object Error : LogLevel(5)
+ public object Error : LogLevel(5)
}
/**
@@ -56,14 +56,14 @@ interface StreamLogger {
*
* @param message A lambda returning the message to log.
*/
- fun d(message: () -> String) = log(LogLevel.Debug, null, message)
+ public fun d(message: () -> String): Unit = log(LogLevel.Debug, null, message)
/**
* Logs an error message.
*
* @param message A lambda returning the message to log.
*/
- fun e(message: () -> String) = log(LogLevel.Error, null, message)
+ public fun e(message: () -> String): Unit = log(LogLevel.Error, null, message)
/**
* Logs an error with an optional message.
@@ -71,7 +71,7 @@ interface StreamLogger {
* @param throwable The error or exception to log.
* @param message An optional lambda returning a message to include.
*/
- fun e(throwable: Throwable, message: (() -> String)?) =
+ public fun e(throwable: Throwable, message: (() -> String)?): Unit =
log(LogLevel.Error, throwable) { message?.invoke() ?: "${throwable.message}" }
/**
@@ -79,21 +79,21 @@ interface StreamLogger {
*
* @param message A lambda returning the message to log.
*/
- fun w(message: () -> String) = log(LogLevel.Warning, null, message)
+ public fun w(message: () -> String): Unit = log(LogLevel.Warning, null, message)
/**
* Logs an informational message.
*
* @param message A lambda returning the message to log.
*/
- fun i(message: () -> String) = log(LogLevel.Info, null, message)
+ public fun i(message: () -> String): Unit = log(LogLevel.Info, null, message)
/**
* Logs a verbose message.
*
* @param message A lambda returning the message to log.
*/
- fun v(message: () -> String) = log(LogLevel.Verbose, null, message)
+ public fun v(message: () -> String): Unit = log(LogLevel.Verbose, null, message)
/**
* Logs a message at the given severity level.
@@ -102,5 +102,5 @@ interface StreamLogger {
* @param throwable An optional [Throwable] associated with the log message.
* @param message A lambda returning the message to log.
*/
- fun log(level: LogLevel, throwable: Throwable?, message: () -> String)
+ public fun log(level: LogLevel, throwable: Throwable?, message: () -> String)
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLoggerProvider.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLoggerProvider.kt
index d370d4d..1e8e649 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLoggerProvider.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/log/StreamLoggerProvider.kt
@@ -16,7 +16,7 @@
package io.getstream.android.core.api.log
import android.util.Log
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import kotlin.coroutines.cancellation.CancellationException
import kotlin.math.min
@@ -26,17 +26,17 @@ import kotlin.math.min
* Implementations decide how loggers are created for specific tags and how log messages are
* emitted.
*/
-@StreamCoreApi
-interface StreamLoggerProvider {
+@StreamInternalApi
+public interface StreamLoggerProvider {
/**
* Creates a [StreamLogger] instance associated with the given tag.
*
* @param tag The tag to identify log messages. Typically corresponds to a class or module name.
* @return A [StreamLogger] that will emit log messages using the given tag.
*/
- fun taggedLogger(tag: String): StreamLogger
+ public fun taggedLogger(tag: String): StreamLogger
- companion object {
+ public companion object {
private const val MAX_LEN = 4000
/**
@@ -55,7 +55,8 @@ interface StreamLoggerProvider {
* @return A [StreamLoggerProvider] that produces Android-backed [StreamLogger] instances.
*/
@JvmStatic
- fun defaultAndroidLogger(
+ @StreamInternalApi
+ public fun defaultAndroidLogger(
minLevel: StreamLogger.LogLevel = StreamLogger.LogLevel.Verbose,
honorAndroidIsLoggable: Boolean = false,
): StreamLoggerProvider =
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamRetryPolicy.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamRetryPolicy.kt
index fa3a044..9d8c5cd 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamRetryPolicy.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamRetryPolicy.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
/**
* **Retry-policy value object** used by Stream’s internal implementations.
@@ -44,9 +44,9 @@ import io.getstream.android.core.annotations.StreamCoreApi
* @param nextBackOffDelayFunction Computes the delay for the upcoming retry. Receives the retry
* index and the previous delay (or `initialDelayMillis` on the first retry).
*/
-@StreamCoreApi
+@StreamInternalApi
@ConsistentCopyVisibility
-data class StreamRetryPolicy
+public data class StreamRetryPolicy
private constructor(
val minRetries: Int,
val maxRetries: Int,
@@ -56,7 +56,7 @@ private constructor(
val giveUpFunction: (retry: Int, cause: Throwable) -> Boolean,
val nextBackOffDelayFunction: (retry: Int, previousDelay: Long) -> Long,
) {
- companion object {
+ public companion object {
/**
* Creates an **exponential back-off** policy.
*
@@ -83,7 +83,7 @@ private constructor(
* @param initialDelayMillis Delay before the *first* retry.
* @param giveUp Custom predicate to override the default “> maxRetries”.
*/
- fun exponential(
+ public fun exponential(
minRetries: Int = 1,
maxRetries: Int = 5,
backoffStepMillis: Long = 250,
@@ -123,7 +123,7 @@ private constructor(
*
* Parameter semantics match [exponential].
*/
- fun linear(
+ public fun linear(
minRetries: Int = 1,
maxRetries: Int = 5,
backoffStepMillis: Long = 250,
@@ -155,7 +155,7 @@ private constructor(
* …
* ```
*/
- fun fixed(
+ public fun fixed(
minRetries: Int = 1,
maxRetries: Int = 5,
delayMillis: Long = 500,
@@ -200,7 +200,7 @@ private constructor(
* @param nextDelay Lambda receives **1-based retry index** and previous delay (or
* `initialDelayMillis` for the first retry) and must return the next delay in **ms**.
*/
- fun custom(
+ public fun custom(
minRetries: Int,
maxRetries: Int,
minBackoffMills: Long,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamTypedKey.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamTypedKey.kt
index b7f5dec..6177590 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamTypedKey.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/StreamTypedKey.kt
@@ -15,16 +15,16 @@
*/
package io.getstream.android.core.api.model
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
/**
* A typed key that can be used to disambiguate between different types of requests.
*
* @property id The unique identifier for the key.
*/
-@StreamCoreApi
-data class StreamTypedKey(val id: Any) {
- companion object {
+@StreamInternalApi
+public data class StreamTypedKey(val id: Any) {
+ public companion object {
/**
* Creates a new [StreamTypedKey] with the given [id] and type [T].
*
@@ -32,7 +32,8 @@ data class StreamTypedKey(val id: Any) {
* @return A new [StreamTypedKey] with the given [id] and type [T].
* @receiver id The unique identifier for the key.
*/
- inline fun Any.asStreamTypedKey() = StreamTypedKey(this)
+ public inline fun Any.asStreamTypedKey(): StreamTypedKey =
+ StreamTypedKey(this)
/**
* Creates a new [StreamTypedKey] with a random [id] and type [T].
@@ -40,6 +41,6 @@ data class StreamTypedKey(val id: Any) {
* @param T The type of the key.
* @return A new [StreamTypedKey] with a random [id] and type [T].
*/
- fun randomExecutionKey() = StreamTypedKey(Any())
+ public fun randomExecutionKey(): StreamTypedKey = StreamTypedKey(Any())
}
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamClientSerializationConfig.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamClientSerializationConfig.kt
index 4e09714..e875531 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamClientSerializationConfig.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamClientSerializationConfig.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.config
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.model.event.StreamClientWsEvent
import io.getstream.android.core.api.serialization.StreamEventSerialization
import io.getstream.android.core.api.serialization.StreamJsonSerialization
@@ -26,9 +26,9 @@ import io.getstream.android.core.api.serialization.StreamJsonSerialization
* @param json The JSON serialization implementation.
* @param eventParser The event parsing implementation.
*/
-@StreamCoreApi
+@StreamInternalApi
@ConsistentCopyVisibility
-data class StreamClientSerializationConfig
+public data class StreamClientSerializationConfig
private constructor(
val json: StreamJsonSerialization? = null,
val eventParser: StreamEventSerialization? = null,
@@ -36,7 +36,7 @@ private constructor(
val internalTypes: Set = setOf("connection.ok", "connection.error", "health.check"),
val alsoExternal: Set = emptySet(),
) {
- companion object {
+ public companion object {
/**
* Creates a default [StreamClientSerializationConfig]. Using the internal implementations.
*
@@ -44,10 +44,10 @@ private constructor(
* @param alsoExternal The event types to also parse as external.
* @return A default [StreamClientSerializationConfig].
*/
- fun default(
+ public fun default(
productEvents: StreamEventSerialization,
alsoExternal: Set = emptySet(),
- ) =
+ ): StreamClientSerializationConfig =
StreamClientSerializationConfig(
productEventSerializers = productEvents,
alsoExternal = alsoExternal,
@@ -61,11 +61,11 @@ private constructor(
* @param alsoExternal The event types to also parse as external.
* @return A [StreamClientSerializationConfig] with the given JSON serialization.
*/
- fun json(
+ public fun json(
serialization: StreamJsonSerialization,
productEvents: StreamEventSerialization,
alsoExternal: Set = emptySet(),
- ) =
+ ): StreamClientSerializationConfig =
StreamClientSerializationConfig(
json = serialization,
productEventSerializers = productEvents,
@@ -80,11 +80,11 @@ private constructor(
* @param alsoExternal The event types to also parse as external.
* @return A [StreamClientSerializationConfig] with the given event parsing.
*/
- fun event(
+ public fun event(
serialization: StreamEventSerialization,
productEvents: StreamEventSerialization,
alsoExternal: Set = emptySet(),
- ) =
+ ): StreamClientSerializationConfig =
StreamClientSerializationConfig(
eventParser = serialization,
productEventSerializers = productEvents,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamHttpConfig.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamHttpConfig.kt
index 787ea40..1a5a0f1 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamHttpConfig.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamHttpConfig.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.config
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import okhttp3.Interceptor
import okhttp3.OkHttpClient
@@ -26,8 +26,8 @@ import okhttp3.OkHttpClient
* @param automaticInterceptors Whether to add automatic interceptors.
* @param configuredInterceptors The configured interceptors.
*/
-@StreamCoreApi
-data class StreamHttpConfig(
+@StreamInternalApi
+public data class StreamHttpConfig(
val httpBuilder: OkHttpClient.Builder,
val automaticInterceptors: Boolean = true,
val configuredInterceptors: Set = emptySet(),
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamSocketConfig.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamSocketConfig.kt
index 4976371..95cf9eb 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamSocketConfig.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamSocketConfig.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.config
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.model.value.StreamApiKey
import io.getstream.android.core.api.model.value.StreamHttpClientInfoHeader
@@ -27,16 +27,16 @@ import io.getstream.android.core.api.model.value.StreamHttpClientInfoHeader
* @param authType The type of authentication used (e.g., "jwt").
* @param clientInfoHeader The client info header.
*/
-@StreamCoreApi
+@StreamInternalApi
@ConsistentCopyVisibility
-data class StreamSocketConfig
+public data class StreamSocketConfig
private constructor(
val url: String,
val apiKey: StreamApiKey,
val authType: String,
val clientInfoHeader: StreamHttpClientInfoHeader,
) {
- companion object {
+ public companion object {
private const val JWT_AUTH_TYPE = "jwt"
private const val ANONYMOUS_AUTH_TYPE = "anonymous"
@@ -48,7 +48,7 @@ private constructor(
* @param clientInfoHeader The client info header.
* @return A JWT-based [StreamSocketConfig].
*/
- fun jwt(
+ public fun jwt(
url: String,
apiKey: StreamApiKey,
clientInfoHeader: StreamHttpClientInfoHeader,
@@ -65,7 +65,7 @@ private constructor(
* @param clientInfoHeader The client info header.
* @return An anonymous [StreamSocketConfig].
*/
- fun anonymous(
+ public fun anonymous(
url: String,
apiKey: StreamApiKey,
clientInfoHeader: StreamHttpClientInfoHeader,
@@ -83,7 +83,7 @@ private constructor(
* @param clientInfoHeader The client info header.
* @return A custom [StreamSocketConfig].
*/
- fun custom(
+ public fun custom(
url: String,
apiKey: StreamApiKey,
authType: String,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectedUser.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectedUser.kt
index 940df5a..85f7da6 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectedUser.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectedUser.kt
@@ -17,7 +17,7 @@ package io.getstream.android.core.api.model.connection
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamPublishedApi
import java.util.Date
import kotlin.collections.Map
@@ -38,22 +38,22 @@ import kotlin.collections.Map
* @property lastActive The date and time when the user was last active.
* @property name The name of the user.
*/
-@StreamCoreApi
+@StreamPublishedApi
@JsonClass(generateAdapter = true)
-class StreamConnectedUser(
- @Json(name = "created_at") val createdAt: Date,
- @Json(name = "id") val id: String,
- @Json(name = "language") val language: String,
- @Json(name = "role") val role: String,
- @Json(name = "updated_at") val updatedAt: Date,
- @Json(name = "blocked_user_ids") val blockedUserIds: List = emptyList(),
- @Json(name = "teams") val teams: List,
- @Json(name = "custom") val custom: Map = emptyMap(),
- @Json(name = "deactivated_at") val deactivatedAt: Date? = null,
- @Json(name = "deleted_at") val deletedAt: Date? = null,
- @Json(name = "image") val image: String? = null,
- @Json(name = "last_active") val lastActive: Date? = null,
- @Json(name = "name") val name: String? = null,
+public class StreamConnectedUser(
+ @Json(name = "created_at") public val createdAt: Date,
+ @Json(name = "id") public val id: String,
+ @Json(name = "language") public val language: String,
+ @Json(name = "role") public val role: String,
+ @Json(name = "updated_at") public val updatedAt: Date,
+ @Json(name = "blocked_user_ids") public val blockedUserIds: List = emptyList(),
+ @Json(name = "teams") public val teams: List,
+ @Json(name = "custom") public val custom: Map = emptyMap(),
+ @Json(name = "deactivated_at") public val deactivatedAt: Date? = null,
+ @Json(name = "deleted_at") public val deletedAt: Date? = null,
+ @Json(name = "image") public val image: String? = null,
+ @Json(name = "last_active") public val lastActive: Date? = null,
+ @Json(name = "name") public val name: String? = null,
) {
/**
* Returns a string representation of the [StreamConnectedUser] object.
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectionState.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectionState.kt
index 21c839b..aa6ca23 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectionState.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/connection/StreamConnectionState.kt
@@ -15,15 +15,15 @@
*/
package io.getstream.android.core.api.model.connection
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamPublishedApi
-@StreamCoreApi
-sealed class StreamConnectionState {
+@StreamPublishedApi
+public sealed class StreamConnectionState {
/** The client is not connected and not trying to connect. Initial state for fresh objects. */
- data object Idle : StreamConnectionState()
+ public data object Idle : StreamConnectionState()
/** The client was connected and is now disconnected. */
- data class Disconnected(val cause: Throwable? = null) : StreamConnectionState()
+ public data class Disconnected(val cause: Throwable? = null) : StreamConnectionState()
/**
* The client is connected and authenticated.
@@ -31,23 +31,23 @@ sealed class StreamConnectionState {
* @property connectedUser The user that is connected to the client.
* @property connectionId The connection ID.
*/
- data class Connected(val connectedUser: StreamConnectedUser, val connectionId: String) :
+ public data class Connected(val connectedUser: StreamConnectedUser, val connectionId: String) :
StreamConnectionState()
/** The client is trying to connect. */
- sealed class Connecting : StreamConnectionState() {
+ public sealed class Connecting : StreamConnectionState() {
/**
* Opening a new connection
*
* @property userId The user ID that is being connected.
*/
- data class Opening(val userId: String) : Connecting()
+ public data class Opening(val userId: String) : Connecting()
/**
* Authenticating a new connection. Socket is open, but not authenticated.
*
* @property userId The user ID that is being connected.
*/
- data class Authenticating(val userId: String) : Connecting()
+ public data class Authenticating(val userId: String) : Connecting()
}
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/event/StreamClientWsEvent.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/event/StreamClientWsEvent.kt
index fd99db3..581709c 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/event/StreamClientWsEvent.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/event/StreamClientWsEvent.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.event
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
/** Represents a WebSocket event for the Stream client. */
-@StreamCoreApi interface StreamClientWsEvent
+@StreamInternalApi public interface StreamClientWsEvent
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/Exceptions.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/Exceptions.kt
index e4356bb..2423e3b 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/Exceptions.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/Exceptions.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.exceptions
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamPublishedApi
import java.io.IOException
/**
@@ -26,8 +26,8 @@ import java.io.IOException
*
* @property message The error message associated with this exception.
*/
-@StreamCoreApi
-open class StreamClientException(message: String = "", cause: Throwable? = null) :
+@StreamPublishedApi
+public open class StreamClientException(message: String = "", cause: Throwable? = null) :
Exception(message, cause)
/**
@@ -41,10 +41,10 @@ open class StreamClientException(message: String = "", cause: Throwable? = null)
* `null` otherwise.
* @property cause The original exception that caused this error, if available, or `null` otherwise.
*/
-@StreamCoreApi
-class StreamEndpointException(
+@StreamPublishedApi
+public class StreamEndpointException(
message: String = "",
- val apiError: StreamEndpointErrorData? = null,
+ public val apiError: StreamEndpointErrorData? = null,
cause: Throwable? = null,
) : IOException(message, cause)
@@ -58,6 +58,6 @@ class StreamEndpointException(
* @property message A descriptive message about the failure.
* @property causes The list of underlying exceptions that caused the failure.
*/
-@StreamCoreApi
-class StreamAggregateException(message: String = "", val causes: List) :
+@StreamPublishedApi
+public class StreamAggregateException(message: String = "", public val causes: List) :
StreamClientException(message)
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/StreamEndpointErrorData.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/StreamEndpointErrorData.kt
index c494d76..3173ad3 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/StreamEndpointErrorData.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/exceptions/StreamEndpointErrorData.kt
@@ -17,7 +17,7 @@ package io.getstream.android.core.api.model.exceptions
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamPublishedApi
/**
* Represents an API error response from the Stream API. This data class encapsulates all the error
@@ -38,7 +38,7 @@ import io.getstream.android.core.annotations.StreamCoreApi
* @property exceptionFields Additional key-value pairs providing extra context about the exception.
* Null if not provided.
*/
-@StreamCoreApi
+@StreamPublishedApi
@JsonClass(generateAdapter = true)
public data class StreamEndpointErrorData(
@Json(name = "code") val code: Int,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamApiKey.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamApiKey.kt
index 5ad2d04..df0e593 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamApiKey.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamApiKey.kt
@@ -15,17 +15,17 @@
*/
package io.getstream.android.core.api.model.value
-import android.annotation.SuppressLint
+import io.getstream.android.core.annotations.StreamPublishedApi
/**
* Represents an API key for authentication.
*
* @property rawValue The raw value of the API key.
*/
-@SuppressLint("StreamCoreApiMissing")
+@StreamPublishedApi
@JvmInline
-value class StreamApiKey private constructor(val rawValue: String) {
- companion object {
+public value class StreamApiKey private constructor(public val rawValue: String) {
+ public companion object {
/**
* Creates a new [StreamApiKey] from a string.
*
@@ -33,7 +33,7 @@ value class StreamApiKey private constructor(val rawValue: String) {
* @return The created [StreamApiKey].
* @throws IllegalArgumentException If the value is blank or contains only digits.
*/
- fun fromString(value: String): StreamApiKey {
+ public fun fromString(value: String): StreamApiKey {
require(value.isNotBlank()) { "API key must not be blank" }
return StreamApiKey(value)
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpClientInfoHeader.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpClientInfoHeader.kt
index 133baf7..b832e63 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpClientInfoHeader.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpClientInfoHeader.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.value
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import java.text.Normalizer
import kotlin.text.iterator
@@ -24,10 +24,10 @@ import kotlin.text.iterator
*
* @property rawValue The raw value of the header.
*/
-@StreamCoreApi
+@StreamInternalApi
@JvmInline
-value class StreamHttpClientInfoHeader private constructor(val rawValue: String) {
- companion object {
+public value class StreamHttpClientInfoHeader private constructor(public val rawValue: String) {
+ public companion object {
/**
* Creates a new [StreamHttpClientInfoHeader] with the given values.
*
@@ -41,7 +41,7 @@ value class StreamHttpClientInfoHeader private constructor(val rawValue: String)
* @return A new [StreamHttpClientInfoHeader] with the given values.
*/
@JvmStatic
- fun create(
+ public fun create(
product: String,
productVersion: String,
os: String,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpUrl.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpUrl.kt
index 43593a3..c465c8b 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpUrl.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamHttpUrl.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.value
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import java.net.URI
/**
@@ -23,10 +23,10 @@ import java.net.URI
*
* @property rawValue The raw value of the HTTP URL.
*/
-@StreamCoreApi
+@StreamInternalApi
@JvmInline
-value class StreamHttpUrl(val rawValue: String) {
- companion object {
+public value class StreamHttpUrl(public val rawValue: String) {
+ public companion object {
/**
* Creates a new [StreamHttpUrl] from a string.
*
@@ -34,7 +34,7 @@ value class StreamHttpUrl(val rawValue: String) {
* @return The created [StreamHttpUrl].
* @throws IllegalArgumentException If the value is blank or not a valid URL.
*/
- fun fromString(value: String): StreamHttpUrl {
+ public fun fromString(value: String): StreamHttpUrl {
require(value.isNotBlank()) { "HTTP URL must not be blank" }
val validURl =
try {
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamToken.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamToken.kt
index fb13e61..4b5df16 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamToken.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamToken.kt
@@ -15,17 +15,17 @@
*/
package io.getstream.android.core.api.model.value
-import android.annotation.SuppressLint
+import io.getstream.android.core.annotations.StreamPublishedApi
/**
* Authentication token value-object.
*
* Always construct it with [fromString] so we can enforce invariants.
*/
-@SuppressLint("StreamCoreApiMissing")
+@StreamPublishedApi
@JvmInline
-value class StreamToken private constructor(val rawValue: String) {
- companion object {
+public value class StreamToken private constructor(public val rawValue: String) {
+ public companion object {
/**
* Creates a new [StreamToken] from a string.
*
@@ -33,7 +33,7 @@ value class StreamToken private constructor(val rawValue: String) {
* @return The created [StreamToken].
* @throws IllegalArgumentException If the token is blank.
*/
- fun fromString(token: String): StreamToken {
+ public fun fromString(token: String): StreamToken {
require(token.isNotBlank()) { "Token must not be blank" }
return StreamToken(token)
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamUserId.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamUserId.kt
index cea497e..69d16de 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamUserId.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamUserId.kt
@@ -15,24 +15,24 @@
*/
package io.getstream.android.core.api.model.value
-import android.annotation.SuppressLint
+import io.getstream.android.core.annotations.StreamPublishedApi
/**
* Represents a user ID.
*
* @property rawValue The raw value of the user ID.
*/
-@SuppressLint("StreamCoreApiMissing")
+@StreamPublishedApi
@JvmInline
-value class StreamUserId private constructor(val rawValue: String) {
- companion object {
+public value class StreamUserId private constructor(public val rawValue: String) {
+ public companion object {
/**
* Creates a [StreamUserId] from a [rawValue].
*
* @param rawValue The raw value of the user ID.
* @return A [StreamUserId] instance.
*/
- fun fromString(rawValue: String): StreamUserId {
+ public fun fromString(rawValue: String): StreamUserId {
require(rawValue.isNotBlank()) { "User ID cannot be blank" }
return StreamUserId(rawValue)
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamWsUrl.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamWsUrl.kt
index 000b544..04fe0f8 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamWsUrl.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/model/value/StreamWsUrl.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.model.value
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import java.net.URI
/**
@@ -23,10 +23,10 @@ import java.net.URI
*
* @property rawValue The raw value of the WebSocket URL.
*/
-@StreamCoreApi
+@StreamInternalApi
@JvmInline
-value class StreamWsUrl private constructor(val rawValue: String) {
- companion object {
+public value class StreamWsUrl private constructor(public val rawValue: String) {
+ public companion object {
/**
* Creates a new [StreamWsUrl] from a string.
*
@@ -34,7 +34,7 @@ value class StreamWsUrl private constructor(val rawValue: String) {
* @return The created [StreamWsUrl].
* @throws IllegalArgumentException If the value is blank or not a valid WS URL.
*/
- fun fromString(value: String): StreamWsUrl {
+ public fun fromString(value: String): StreamWsUrl {
require(value.isNotBlank()) { "WS URL must not be blank" }
val validUrl =
try {
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamBatcher.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamBatcher.kt
index 46dbaaa..ac70437 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamBatcher.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamBatcher.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.processing
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.internal.processing.StreamBatcherImpl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
@@ -44,15 +44,15 @@ import kotlinx.coroutines.channels.Channel
* - Coalescing high-frequency events (socket messages, UI updates) into fewer handler invocations.
* - Rate-limiting downstream work (parsing, I/O, UI recomposition).
*/
-@StreamCoreApi
-interface StreamBatcher {
+@StreamInternalApi
+public interface StreamBatcher {
/**
* Starts the processor if it's not already running.
*
* @return `Result.success(Unit)` if the processor was started successfully; otherwise a
* `Result.failure(cause)` describing why the start failed.
*/
- suspend fun start(): Result
+ public suspend fun start(): Result
/**
* Registers the batch handler to be invoked whenever a batch is ready.
@@ -67,7 +67,7 @@ interface StreamBatcher {
*
* Calling this method replaces any previously registered handler.
*/
- fun onBatch(handler: suspend (List, Long, Int) -> Unit)
+ public fun onBatch(handler: suspend (List, Long, Int) -> Unit)
/**
* Enqueues a single item for debounced processing.
@@ -81,7 +81,7 @@ interface StreamBatcher {
*
* @param item The item to enqueue.
*/
- suspend fun enqueue(item: T): Result
+ public suspend fun enqueue(item: T): Result
/**
* Enqueues a single item for debounced processing.
@@ -91,7 +91,7 @@ interface StreamBatcher {
* - `true` if the item was accepted,
* - `false` if the processor is closed/stopped or cannot accept the item.
*/
- fun offer(item: T): Boolean
+ public fun offer(item: T): Boolean
/**
* Stops the processor and releases resources.
@@ -103,7 +103,7 @@ interface StreamBatcher {
* @return `Result.success(Unit)` on a successful stop; `Result.failure(cause)` if stopping
* failed.
*/
- fun stop(): Result
+ public fun stop(): Result
}
/**
@@ -118,8 +118,8 @@ interface StreamBatcher {
* @param channelCapacity The capacity of the underlying channel.
* @return A new [StreamBatcher] instance.
*/
-@StreamCoreApi
-fun StreamBatcher(
+@StreamInternalApi
+public fun StreamBatcher(
scope: CoroutineScope,
batchSize: Int = 10,
initialDelayMs: Long = 100L,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamRetryProcessor.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamRetryProcessor.kt
index 3e725f9..073f86a 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamRetryProcessor.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamRetryProcessor.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.processing
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.log.StreamLogger
import io.getstream.android.core.api.model.StreamRetryPolicy
import io.getstream.android.core.internal.processing.StreamRetryProcessorImpl
@@ -43,8 +43,8 @@ import io.getstream.android.core.internal.processing.StreamRetryProcessorImpl
* @return A [Result] wrapping either the successful value or the final error after all retries have
* been exhausted.
*/
-@StreamCoreApi
-interface StreamRetryProcessor {
+@StreamInternalApi
+public interface StreamRetryProcessor {
/**
* Executes [block] with the supplied [policy], retrying on failure.
*
@@ -53,7 +53,7 @@ interface StreamRetryProcessor {
* @param block The suspending operation to execute. It should throw on failure; the processor
* handles re-invocation.
*/
- suspend fun retry(policy: StreamRetryPolicy, block: suspend () -> T): Result
+ public suspend fun retry(policy: StreamRetryPolicy, block: suspend () -> T): Result
}
/**
@@ -62,6 +62,6 @@ interface StreamRetryProcessor {
* @param logger The logger to use for logging retry attempts.
* @return A new [StreamRetryProcessor] instance.
*/
-@StreamCoreApi
-fun StreamRetryProcessor(logger: StreamLogger): StreamRetryProcessor =
+@StreamInternalApi
+public fun StreamRetryProcessor(logger: StreamLogger): StreamRetryProcessor =
StreamRetryProcessorImpl(logger)
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSerialProcessingQueue.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSerialProcessingQueue.kt
index a42f1ed..f068c48 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSerialProcessingQueue.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSerialProcessingQueue.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.processing
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.log.StreamLogger
import io.getstream.android.core.internal.processing.StreamSerialProcessingQueueImpl
import kotlinx.coroutines.CoroutineScope
@@ -46,8 +46,8 @@ import kotlinx.coroutines.channels.Channel
* the job may still run if it was already accepted by the queue (implementation-specific). Call
* [stop] to cancel/flush work at the queue level.
*/
-@StreamCoreApi
-interface StreamSerialProcessingQueue {
+@StreamInternalApi
+public interface StreamSerialProcessingQueue {
/**
* Submits a suspending [job] for **serialized** execution.
*
@@ -65,7 +65,7 @@ interface StreamSerialProcessingQueue {
* job once accepted (implementation-specific). Use [stop] to cancel at the queue level.
* - **Exceptions:** Exceptions thrown by [job] are captured and returned via [Result.failure].
*/
- suspend fun submit(job: suspend () -> T): Result
+ public suspend fun submit(job: suspend () -> T): Result
/**
* Starts the processor if it's not already running.
@@ -73,7 +73,7 @@ interface StreamSerialProcessingQueue {
* @return `Result.success(Unit)` if the processor was started successfully; otherwise a
* `Result.failure(cause)` describing why the start failed.
*/
- suspend fun start(): Result
+ public suspend fun start(): Result
/**
* Stops the processor and **fails** outstanding work.
@@ -89,7 +89,7 @@ interface StreamSerialProcessingQueue {
* @return [Result.success] if the processor was stopped successfully; otherwise a
* [Result.failure] describing why the stop failed.
*/
- suspend fun stop(timeout: Long? = null): Result
+ public suspend fun stop(timeout: Long? = null): Result
}
/**
@@ -102,8 +102,8 @@ interface StreamSerialProcessingQueue {
* @param capacity The capacity of the internal queue.
* @return A new [StreamSerialProcessingQueue] instance.
*/
-@StreamCoreApi
-fun StreamSerialProcessingQueue(
+@StreamInternalApi
+public fun StreamSerialProcessingQueue(
logger: StreamLogger,
scope: CoroutineScope,
autoStart: Boolean = true,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSingleFlightProcessor.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSingleFlightProcessor.kt
index a03b716..8956af5 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSingleFlightProcessor.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/processing/StreamSingleFlightProcessor.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.processing
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.model.StreamTypedKey
import io.getstream.android.core.internal.processing.StreamSingleFlightProcessorImpl
import kotlinx.coroutines.CancellationException
@@ -53,8 +53,8 @@ import kotlinx.coroutines.CoroutineScope
*
* Implementations must be safe for concurrent use.
*/
-@StreamCoreApi
-interface StreamSingleFlightProcessor {
+@StreamInternalApi
+public interface StreamSingleFlightProcessor {
/**
* Runs [block], ensuring that **at most one execution** for [key] is in flight. Concurrent
* callers with the same [key] await the same shared execution and receive its [Result].
@@ -67,32 +67,32 @@ interface StreamSingleFlightProcessor {
* cancelled. If the *awaiting caller* is cancelled, a [CancellationException] is thrown to
* that caller instead.
*/
- suspend fun run(key: StreamTypedKey, block: suspend () -> T): Result
+ public suspend fun run(key: StreamTypedKey, block: suspend () -> T): Result
/**
* Checks if there is an in-flight execution for [key].
*
* @param key The key to check.
*/
- fun has(key: StreamTypedKey): Boolean
+ public fun has(key: StreamTypedKey): Boolean
/**
* Cancels the current in-flight execution for [key], if any. Joiners will receive
* `Result.failure(CancellationException)`. No-op if there is no in-flight execution.
*/
- fun cancel(key: StreamTypedKey): Result
+ public fun cancel(key: StreamTypedKey): Result
/**
* Clears internal bookkeeping. Useful if another component owns lifecycle/cancellation and you
* want to drop references.
*/
- fun clear(cancelRunning: Boolean = true): Result
+ public fun clear(cancelRunning: Boolean = true): Result
/**
* Stops all execution and shuts down the runner. No further jobs are accepted. Stop is a
* destructive action.
*/
- fun stop(): Result
+ public fun stop(): Result
}
/**
@@ -101,6 +101,6 @@ interface StreamSingleFlightProcessor {
* @param scope The coroutine scope to use for running the in-flight executions.
* @return A new [StreamSingleFlightProcessor] instance.
*/
-@StreamCoreApi
-fun StreamSingleFlightProcessor(scope: CoroutineScope): StreamSingleFlightProcessor =
+@StreamInternalApi
+public fun StreamSingleFlightProcessor(scope: CoroutineScope): StreamSingleFlightProcessor =
StreamSingleFlightProcessorImpl(scope)
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamEventSerialization.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamEventSerialization.kt
index fa53008..9179068 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamEventSerialization.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamEventSerialization.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.serialization
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.model.event.StreamClientWsEvent
import io.getstream.android.core.internal.serialization.StreamClientEventSerializationImpl
@@ -27,8 +27,8 @@ import io.getstream.android.core.internal.serialization.StreamClientEventSeriali
*
* @param T The product event type handled by this interface.
*/
-@StreamCoreApi
-interface StreamEventSerialization {
+@StreamInternalApi
+public interface StreamEventSerialization {
/**
* Encodes a product event into a [String] suitable for transport or storage.
@@ -37,7 +37,7 @@ interface StreamEventSerialization {
* @return `Result.success(String)` when encoding succeeds, or `Result.failure(Throwable)` when
* the process fails.
*/
- fun serialize(data: T): Result
+ public fun serialize(data: T): Result
/**
* Decodes a product event from a [String] representation.
@@ -46,7 +46,7 @@ interface StreamEventSerialization {
* @return `Result.success(T)` when decoding succeeds, or `Result.failure(Throwable)` when the
* process fails.
*/
- fun deserialize(raw: String): Result
+ public fun deserialize(raw: String): Result
}
/**
@@ -57,7 +57,7 @@ interface StreamEventSerialization {
* deserialization.
* @return A new [StreamEventSerialization] instance.
*/
-@StreamCoreApi
-fun StreamEventSerialization(
+@StreamInternalApi
+public fun StreamEventSerialization(
jsonParser: StreamJsonSerialization
): StreamEventSerialization = StreamClientEventSerializationImpl(jsonParser)
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamJsonSerialization.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamJsonSerialization.kt
index 140fd1b..7fd01e5 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamJsonSerialization.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/serialization/StreamJsonSerialization.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.serialization
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
/**
* General contract for JSON serialization and deserialization.
@@ -27,8 +27,8 @@ import io.getstream.android.core.annotations.StreamCoreApi
* Implementations are expected to provide robust error handling and return results wrapped in
* [Result].
*/
-@StreamCoreApi
-interface StreamJsonSerialization {
+@StreamInternalApi
+public interface StreamJsonSerialization {
/**
* Converts an object into its JSON string representation.
*
@@ -36,7 +36,7 @@ interface StreamJsonSerialization {
* @return A [Result] containing the JSON string if successful, or a failure with the underlying
* exception if serialization fails.
*/
- fun toJson(any: Any): Result
+ public fun toJson(any: Any): Result
/**
* Converts a JSON string into an object of the specified class.
@@ -46,7 +46,7 @@ interface StreamJsonSerialization {
* @return A [Result] containing the deserialized object if successful, or a failure with the
* underlying exception if deserialization fails.
*/
- fun fromJson(raw: String, clazz: Class): Result
+ public fun fromJson(raw: String, clazz: Class): Result
}
/**
@@ -57,7 +57,7 @@ interface StreamJsonSerialization {
* underlying exception if deserialization fails.
* @see [StreamJsonSerialization.fromJson]
*/
-@StreamCoreApi
+@StreamInternalApi
@JvmSynthetic
-inline fun StreamJsonSerialization.fromJson(raw: String): Result =
+public inline fun StreamJsonSerialization.fromJson(raw: String): Result =
fromJson(raw, T::class.java)
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamConnectionIdHolder.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamConnectionIdHolder.kt
index 0078cc1..a8bea23 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamConnectionIdHolder.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamConnectionIdHolder.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.socket
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.internal.socket.connection.StreamConnectionIdHolderImpl
/**
@@ -28,14 +28,14 @@ import io.getstream.android.core.internal.socket.connection.StreamConnectionIdHo
* the expected value (or `null` if no connection ID is set). On failure, the [Result] contains the
* relevant [Throwable].
*/
-@StreamCoreApi
-interface StreamConnectionIdHolder {
+@StreamInternalApi
+public interface StreamConnectionIdHolder {
/**
* Clears the stored connection ID.
*
* @return A [Result] indicating success, or containing an error if the operation fails.
*/
- fun clear(): Result
+ public fun clear(): Result
/**
* Stores the given connection ID.
@@ -44,7 +44,7 @@ interface StreamConnectionIdHolder {
* @return A [Result] containing the stored connection ID if successful, or an error if the
* operation fails.
*/
- fun setConnectionId(connectionId: String): Result
+ public fun setConnectionId(connectionId: String): Result
/**
* Retrieves the stored connection ID.
@@ -52,9 +52,9 @@ interface StreamConnectionIdHolder {
* @return A [Result] containing the connection ID if available, `null` if none is set, or an
* error if the operation fails.
*/
- fun getConnectionId(): Result
+ public fun getConnectionId(): Result
}
/** Creates a new [StreamConnectionIdHolder] instance. */
-@StreamCoreApi
-fun StreamConnectionIdHolder(): StreamConnectionIdHolder = StreamConnectionIdHolderImpl()
+@StreamInternalApi
+public fun StreamConnectionIdHolder(): StreamConnectionIdHolder = StreamConnectionIdHolderImpl()
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocket.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocket.kt
index 59c5f46..b8674ad 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocket.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocket.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.socket
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.log.StreamLogger
import io.getstream.android.core.api.model.config.StreamSocketConfig
import io.getstream.android.core.api.socket.listeners.StreamWebSocketListener
@@ -30,8 +30,8 @@ import io.getstream.android.core.internal.socket.StreamWebSocketImpl
*
* @param T The type of listener used to receive WebSocket events.
*/
-@StreamCoreApi
-interface StreamWebSocket : StreamSubscriptionManager {
+@StreamInternalApi
+public interface StreamWebSocket : StreamSubscriptionManager {
/**
* Opens the WebSocket connection using the provided configuration.
*
@@ -39,7 +39,7 @@ interface StreamWebSocket : StreamSubscriptionManag
* authentication, and optional headers.
* @return A [Result] indicating whether the connection was successfully initiated.
*/
- fun open(config: StreamSocketConfig): Result
+ public fun open(config: StreamSocketConfig): Result
/**
* Closes the WebSocket connection.
@@ -48,7 +48,7 @@ interface StreamWebSocket : StreamSubscriptionManag
*
* @return A [Result] indicating whether the connection was successfully closed.
*/
- fun close(): Result
+ public fun close(): Result
/**
* Sends binary data through the WebSocket connection.
@@ -57,7 +57,7 @@ interface StreamWebSocket : StreamSubscriptionManag
* @return A [Result] containing the same [ByteArray] if successfully sent, or a failure if
* sending failed.
*/
- fun send(data: ByteArray): Result
+ public fun send(data: ByteArray): Result
/**
* Sends a text message through the WebSocket connection.
@@ -66,7 +66,7 @@ interface StreamWebSocket : StreamSubscriptionManag
* @return A [Result] containing the same [String] if successfully sent, or a failure if sending
* failed.
*/
- fun send(text: String): Result
+ public fun send(text: String): Result
}
/**
@@ -77,8 +77,8 @@ interface StreamWebSocket : StreamSubscriptionManag
* @param subscriptionManager The [StreamSubscriptionManager] to use for managing subscriptions.
* @return A new [StreamWebSocket] instance.
*/
-@StreamCoreApi
-fun StreamWebSocket(
+@StreamInternalApi
+public fun StreamWebSocket(
logger: StreamLogger,
socketFactory: StreamWebSocketFactory,
subscriptionManager: StreamSubscriptionManager,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocketFactory.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocketFactory.kt
index 247970c..e1a83f7 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocketFactory.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/StreamWebSocketFactory.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.socket
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.log.StreamLogger
import io.getstream.android.core.api.model.config.StreamSocketConfig
import io.getstream.android.core.internal.socket.factory.StreamWebSocketFactoryImpl
@@ -33,8 +33,8 @@ import okhttp3.WebSocketListener
* The created socket will be configured with the given [StreamSocketConfig], and bound to the
* provided [WebSocketListener] for low-level socket events.
*/
-@StreamCoreApi
-interface StreamWebSocketFactory {
+@StreamInternalApi
+public interface StreamWebSocketFactory {
/**
* Creates a new [WebSocket] instance.
*
@@ -45,7 +45,7 @@ interface StreamWebSocketFactory {
* @return A [Result] wrapping the created [WebSocket]. On success, the returned [WebSocket]
* will be connected and bound to [listener].
*/
- fun create(
+ public fun create(
streamSocketConfig: StreamSocketConfig,
listener: WebSocketListener,
): Result
@@ -58,8 +58,8 @@ interface StreamWebSocketFactory {
* @param logger The logger to use for logging.
* @return A [StreamWebSocketFactory] instance.
*/
-@StreamCoreApi
-fun StreamWebSocketFactory(
+@StreamInternalApi
+public fun StreamWebSocketFactory(
okHttpClient: OkHttpClient = OkHttpClient(),
logger: StreamLogger,
): StreamWebSocketFactory = StreamWebSocketFactoryImpl(okHttpClient = okHttpClient, logger = logger)
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamClientListener.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamClientListener.kt
index 548a021..d3f64fd 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamClientListener.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamClientListener.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.socket.listeners
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.model.connection.StreamConnectionState
/**
@@ -24,26 +24,26 @@ import io.getstream.android.core.api.model.connection.StreamConnectionState
* This interface defines methods to handle socket state changes and events. Implement this
* interface to receive updates about the socket connection state and incoming events.
*/
-@StreamCoreApi
-interface StreamClientListener {
+@StreamInternalApi
+public interface StreamClientListener {
/**
* Called when the socket connection state changes.
*
* @param state The new state of the WebSocket connection.
*/
- fun onState(state: StreamConnectionState) {}
+ public fun onState(state: StreamConnectionState) {}
/**
* Called when a new event is received from the socket.
*
* @param event The event received from the WebSocket.
*/
- fun onEvent(event: Any) {}
+ public fun onEvent(event: Any) {}
/**
* Called when an error occurs on the client.
*
* @param err The error that occurred.
*/
- fun onError(err: Throwable) {}
+ public fun onError(err: Throwable) {}
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamWebSocketListener.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamWebSocketListener.kt
index b873451..9d72c53 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamWebSocketListener.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/listeners/StreamWebSocketListener.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.socket.listeners
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.subscribe.StreamSubscription
import okhttp3.Response
import okio.ByteString
@@ -49,28 +49,28 @@ import okio.ByteString
* @see StreamSubscription For lifecycle management of subscriptions.
* @see okhttp3.WebSocketListener For the underlying OkHttp implementation.
*/
-@StreamCoreApi
-interface StreamWebSocketListener {
+@StreamInternalApi
+public interface StreamWebSocketListener {
/**
* Called when the socket connection is established.
*
* @param response The handshake response returned by the server.
*/
- fun onOpen(response: Response) {}
+ public fun onOpen(response: Response) {}
/**
* Called when a new binary message is received from the server.
*
* @param bytes The raw binary payload received.
*/
- fun onMessage(bytes: ByteString) {}
+ public fun onMessage(bytes: ByteString) {}
/**
* Called when a new text message is received from the server.
*
* @param text The UTF-8 encoded text payload received.
*/
- fun onMessage(text: String) {}
+ public fun onMessage(text: String) {}
/**
* Called when an error occurs on the socket.
@@ -78,7 +78,7 @@ interface StreamWebSocketListener {
* @param t The throwable cause of the failure.
* @param response The optional server response associated with the error.
*/
- fun onFailure(t: Throwable, response: Response?) {}
+ public fun onFailure(t: Throwable, response: Response?) {}
/**
* Called when the socket connection has been closed.
@@ -86,7 +86,7 @@ interface StreamWebSocketListener {
* @param code The closure status code as defined by RFC 6455.
* @param reason The reason message provided by the peer, if any.
*/
- fun onClosed(code: Int, reason: String) {}
+ public fun onClosed(code: Int, reason: String) {}
/**
* Called when the socket is about to close.
@@ -94,5 +94,5 @@ interface StreamWebSocketListener {
* @param code The closure status code as defined by RFC 6455.
* @param reason The reason message provided by the peer, if any.
*/
- fun onClosing(code: Int, reason: String) {}
+ public fun onClosing(code: Int, reason: String) {}
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/monitor/StreamHealthMonitor.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/monitor/StreamHealthMonitor.kt
index dd231f0..322cd6d 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/socket/monitor/StreamHealthMonitor.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/socket/monitor/StreamHealthMonitor.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.socket.monitor
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.log.StreamLogger
import io.getstream.android.core.internal.socket.monitor.StreamHealthMonitorImpl
import kotlin.time.ExperimentalTime
@@ -31,8 +31,8 @@ import kotlinx.coroutines.CoroutineScope
* - Call [acknowledgeHeartbeat] when receiving a valid "I'm alive" signal.
* - Start and stop the monitor as needed.
*/
-@StreamCoreApi
-interface StreamHealthMonitor {
+@StreamInternalApi
+public interface StreamHealthMonitor {
/**
* Registers a callback that is invoked at every heartbeat interval.
*
@@ -41,7 +41,7 @@ interface StreamHealthMonitor {
*
* @param callback A function to be called on each heartbeat tick.
*/
- fun onHeartbeat(callback: suspend () -> Unit)
+ public fun onHeartbeat(callback: suspend () -> Unit)
/**
* Registers a callback that is invoked when the liveness threshold is exceeded.
@@ -51,7 +51,7 @@ interface StreamHealthMonitor {
*
* @param callback A function to be called when the liveness timeout occurs.
*/
- fun onUnhealthy(callback: suspend () -> Unit)
+ public fun onUnhealthy(callback: suspend () -> Unit)
/**
* Acknowledges a heartbeat signal.
@@ -59,18 +59,18 @@ interface StreamHealthMonitor {
* This should be called whenever the monitored system successfully responds, indicating that it
* is alive and healthy. Resets the liveness timer.
*/
- fun acknowledgeHeartbeat()
+ public fun acknowledgeHeartbeat()
/** Starts the health monitor, beginning the heartbeat and liveness checks. */
- fun start()
+ public fun start()
/** Stops the health monitor, halting heartbeat and liveness checks. */
- fun stop()
+ public fun stop()
}
@OptIn(ExperimentalTime::class)
-@StreamCoreApi
-fun StreamHealthMonitor(
+@StreamInternalApi
+public fun StreamHealthMonitor(
logger: StreamLogger,
scope: CoroutineScope,
interval: Long = StreamHealthMonitorImpl.INTERVAL,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscription.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscription.kt
index 85c757c..002f24a 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscription.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscription.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.subscribe
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamPublishedApi
/**
* Handle returned by every **Stream** `subscribe(…)` call.
@@ -29,8 +29,8 @@ import io.getstream.android.core.annotations.StreamCoreApi
* Instances are **single-shot**: once you invoke [cancel] the subscription is permanently
* terminated and calling `cancel()` again has no effect.
*/
-@StreamCoreApi
-interface StreamSubscription {
+@StreamPublishedApi
+public interface StreamSubscription {
/**
* Terminates this subscription.
*
@@ -40,5 +40,5 @@ interface StreamSubscription {
*
* The operation is idempotent; invoking it multiple times is safe.
*/
- fun cancel()
+ public fun cancel()
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscriptionManager.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscriptionManager.kt
index 4726804..3d2b0a8 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscriptionManager.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/subscribe/StreamSubscriptionManager.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.subscribe
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import io.getstream.android.core.api.log.StreamLogger
import io.getstream.android.core.internal.subscribe.StreamSubscriptionManagerImpl
@@ -37,16 +37,16 @@ import io.getstream.android.core.internal.subscribe.StreamSubscriptionManagerImp
*
* @param T the listener type (often a function type, e.g. `(Event) -> Unit`)
*/
-@StreamCoreApi
-interface StreamSubscriptionManager {
+@StreamInternalApi
+public interface StreamSubscriptionManager {
/**
* Subscription behavior options.
*
* @property retention Controls how the manager retains the listener reference.
*/
- data class Options(val retention: Retention = Retention.AUTO_REMOVE) {
+ public data class Options(val retention: Retention = Retention.AUTO_REMOVE) {
/** Retention policy for a subscribed listener. */
- enum class Retention {
+ public enum class Retention {
/**
* The manager keeps only an ephemeral reference. If caller code drops all references to
* the listener (and does not call `cancel()`), the listener is automatically removed
@@ -84,7 +84,7 @@ interface StreamSubscriptionManager {
* @return `Result.success(StreamSubscription)` when the listener was added;
* `Result.failure(Throwable)` if the operation cannot be completed (e.g., capacity limits).
*/
- fun subscribe(listener: T, options: Options = Options()): Result
+ public fun subscribe(listener: T, options: Options = Options()): Result
/**
* Removes **all** listeners and releases related resources.
@@ -96,7 +96,7 @@ interface StreamSubscriptionManager {
* @return `Result.success(Unit)` if cleared successfully; `Result.failure(Throwable)`
* otherwise.
*/
- fun clear(): Result
+ public fun clear(): Result
/**
* Executes [block] for every currently registered listener.
@@ -111,7 +111,7 @@ interface StreamSubscriptionManager {
* @return `Result.success(Unit)` on normal completion; `Result.failure(Throwable)` if iteration
* fails.
*/
- fun forEach(block: (T) -> Unit): Result
+ public fun forEach(block: (T) -> Unit): Result
}
/**
@@ -123,8 +123,8 @@ interface StreamSubscriptionManager {
* @param maxWeakSubscriptions The maximum number of weak listeners.
* @return A new [StreamSubscriptionManager] instance.
*/
-@StreamCoreApi
-fun StreamSubscriptionManager(
+@StreamInternalApi
+public fun StreamSubscriptionManager(
logger: StreamLogger,
maxStrongSubscriptions: Int = StreamSubscriptionManagerImpl.MAX_LISTENERS,
maxWeakSubscriptions: Int = StreamSubscriptionManagerImpl.MAX_LISTENERS,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Catching.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Catching.kt
index f7b820b..8cc6591 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Catching.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Catching.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.utils
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@@ -27,9 +27,9 @@ import kotlin.coroutines.cancellation.CancellationException
* - On **cancellation**: **rethrows** [CancellationException].
* - On **other exceptions**: `Result.failure(cause)`.
*/
-@StreamCoreApi
+@StreamInternalApi
@OptIn(ExperimentalContracts::class)
-inline fun runCatchingCancellable(block: () -> T): Result {
+public inline fun runCatchingCancellable(block: () -> T): Result {
contract { callsInPlace(block, InvocationKind.AT_MOST_ONCE) }
return try {
Result.success(block())
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Map.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Map.kt
index 7c4ed42..db5dd72 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Map.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Map.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.utils
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import java.util.concurrent.ConcurrentMap
/**
@@ -25,8 +25,11 @@ import java.util.concurrent.ConcurrentMap
* @param defaultValue The function to compute the value.
* @return The value for the given key.
*/
-@StreamCoreApi
-inline fun ConcurrentMap.streamComputeIfAbsent(key: K, defaultValue: () -> V): V {
+@StreamInternalApi
+public inline fun ConcurrentMap.streamComputeIfAbsent(
+ key: K,
+ defaultValue: () -> V,
+): V {
this[key]?.let {
return it
}
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Result.kt b/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Result.kt
index b66c9ac..d4db062 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Result.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/api/utils/Result.kt
@@ -15,7 +15,7 @@
*/
package io.getstream.android.core.api.utils
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamInternalApi
import kotlin.coroutines.cancellation.CancellationException
/**
@@ -32,6 +32,6 @@ import kotlin.coroutines.cancellation.CancellationException
* failure if this [Result] is a failure.
* @throws Throwable if [transform] throws, including [CancellationException].
*/
-@StreamCoreApi
-inline fun Result.flatMap(transform: (T) -> Result): Result =
+@StreamInternalApi
+public inline fun Result.flatMap(transform: (T) -> Result): Result =
fold(onSuccess = { transform(it) }, onFailure = { Result.failure(it) })
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/internal/model/events/StreamHealthCheckEvent.kt b/stream-android-core/src/main/java/io/getstream/android/core/internal/model/events/StreamHealthCheckEvent.kt
index 19ee535..013d4c7 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/internal/model/events/StreamHealthCheckEvent.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/internal/model/events/StreamHealthCheckEvent.kt
@@ -17,11 +17,11 @@ package io.getstream.android.core.internal.model.events
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
-import io.getstream.android.core.annotations.StreamCoreApi
+import io.getstream.android.core.annotations.StreamPublishedApi
import io.getstream.android.core.api.model.event.StreamClientWsEvent
import java.util.Date
-@StreamCoreApi
+@StreamPublishedApi
@JsonClass(generateAdapter = true)
internal data class StreamHealthCheckEvent(
@Json(name = "connection_id") val connectionId: String,
diff --git a/stream-android-core/src/main/java/io/getstream/android/core/internal/processing/StreamRestartableChannel.kt b/stream-android-core/src/main/java/io/getstream/android/core/internal/processing/StreamRestartableChannel.kt
index abb5ce5..f879170 100644
--- a/stream-android-core/src/main/java/io/getstream/android/core/internal/processing/StreamRestartableChannel.kt
+++ b/stream-android-core/src/main/java/io/getstream/android/core/internal/processing/StreamRestartableChannel.kt
@@ -19,6 +19,7 @@ package io.getstream.android.core.internal.processing
import java.util.concurrent.atomic.AtomicReference
import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.selects.SelectClause1
import kotlinx.coroutines.selects.SelectClause2
@@ -29,6 +30,7 @@ import kotlinx.coroutines.selects.SelectClause2
* - When [start] is called after the channel was closed-for-send, it swaps in a fresh channel.
* - Adds `*Safe` helpers that wrap send/trySend/close in Result for ergonomic error handling.
*/
+@OptIn(DelicateCoroutinesApi::class)
internal class StreamRestartableChannel(private val capacity: Int = Channel.BUFFERED) :
Channel {