diff --git a/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/Connector.kt b/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/Connector.kt new file mode 100644 index 00000000..45fd9b5b --- /dev/null +++ b/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/Connector.kt @@ -0,0 +1,20 @@ +package com.powersync + +import com.powersync.connectors.PowerSyncBackendConnector +import com.powersync.connectors.PowerSyncCredentials + +public interface SwiftBackendConnector { + public suspend fun fetchCredentials(): PowerSyncResult + + public suspend fun uploadData(): PowerSyncResult +} + +public fun swiftBackendConnectorToPowerSyncConnector(connector: SwiftBackendConnector): PowerSyncBackendConnector = + object : PowerSyncBackendConnector() { + override suspend fun fetchCredentials(): PowerSyncCredentials? = + handleLockResult(connector.fetchCredentials()) as PowerSyncCredentials? + + override suspend fun uploadData(database: PowerSyncDatabase) { + handleLockResult(connector.uploadData()) + } + } diff --git a/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/Locks.kt b/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/Locks.kt index dbb5297c..9116bcfe 100644 --- a/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/Locks.kt +++ b/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/Locks.kt @@ -15,7 +15,7 @@ import com.powersync.db.internal.PowerSyncTransaction */ public sealed class PowerSyncResult { public data class Success( - val value: Any, + val value: Any?, ) : PowerSyncResult() public data class Failure( @@ -26,7 +26,7 @@ public sealed class PowerSyncResult { // Throws the [PowerSyncException] if the result is a failure, or returns the value if it is a success. // We throw the exception on behalf of the Swift SDK. @Throws(PowerSyncException::class) -private fun handleLockResult(result: PowerSyncResult): Any { +internal fun handleLockResult(result: PowerSyncResult): Any? { when (result) { is PowerSyncResult.Failure -> { throw result.exception @@ -41,13 +41,13 @@ private fun handleLockResult(result: PowerSyncResult): Any { public class LockContextWrapper( private val handler: (context: ConnectionContext) -> PowerSyncResult, ) : ThrowableLockCallback { - override fun execute(context: ConnectionContext): Any = handleLockResult(handler(context)) + override fun execute(context: ConnectionContext): Any = handleLockResult(handler(context))!! } public class TransactionContextWrapper( private val handler: (context: PowerSyncTransaction) -> PowerSyncResult, ) : ThrowableTransactionCallback { - override fun execute(transaction: PowerSyncTransaction): Any = handleLockResult(handler(transaction)) + override fun execute(transaction: PowerSyncTransaction): Any = handleLockResult(handler(transaction))!! } public fun wrapContextHandler(handler: (context: ConnectionContext) -> PowerSyncResult): ThrowableLockCallback = diff --git a/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/SDK.kt b/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/SDK.kt index 6204de80..81524368 100644 --- a/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/SDK.kt +++ b/PowerSyncKotlin/src/appleMain/kotlin/com/powersync/SDK.kt @@ -2,10 +2,14 @@ package com.powersync +import com.powersync.db.crud.CrudTransaction import com.powersync.sync.SyncClientConfiguration import com.powersync.sync.SyncOptions import io.ktor.client.plugins.logging.LogLevel import io.ktor.client.plugins.logging.Logging +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.map import io.ktor.client.plugins.logging.Logger as KtorLogger /** @@ -88,3 +92,16 @@ public fun createSyncOptions( userAgent = userAgent, clientConfiguration = createExtendedSyncClientConfiguration(loggingConfig), ) + +public fun errorHandledCrudTransactions(db: PowerSyncDatabase): Flow = + db + .getCrudTransactions() + .map { + PowerSyncResult.Success(it) + }.catch { + if (it is PowerSyncException) { + emit(PowerSyncResult.Failure(it)) + } else { + throw it + } + } diff --git a/core/src/commonMain/kotlin/com/powersync/PowerSyncDatabase.kt b/core/src/commonMain/kotlin/com/powersync/PowerSyncDatabase.kt index 977b8d1a..de2b1399 100644 --- a/core/src/commonMain/kotlin/com/powersync/PowerSyncDatabase.kt +++ b/core/src/commonMain/kotlin/com/powersync/PowerSyncDatabase.kt @@ -173,8 +173,7 @@ public interface PowerSyncDatabase : Queries { * * If there is no local data to upload, returns an empty flow. */ - @Throws(PowerSyncException::class, CancellationException::class) - public suspend fun getCrudTransactions(): Flow + public fun getCrudTransactions(): Flow /** * Convenience method to get the current version of PowerSync. diff --git a/core/src/commonMain/kotlin/com/powersync/db/PowerSyncDatabaseImpl.kt b/core/src/commonMain/kotlin/com/powersync/db/PowerSyncDatabaseImpl.kt index 92ec9cf2..1b24f999 100644 --- a/core/src/commonMain/kotlin/com/powersync/db/PowerSyncDatabaseImpl.kt +++ b/core/src/commonMain/kotlin/com/powersync/db/PowerSyncDatabaseImpl.kt @@ -270,7 +270,7 @@ internal class PowerSyncDatabaseImpl( }) } - override suspend fun getCrudTransactions(): Flow = + override fun getCrudTransactions(): Flow = flow { waitReady() var lastItemId = -1