diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac101e..c6d3b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.1.1 (unreleased) +## 1.2.0 * Improved `CrudBatch` and `CrudTransaction` `complete` function extensions. Developers no longer need to specify `nil` as an argument for `writeCheckpoint` when calling `CrudBatch.complete`. The base `complete` functions still accept an optional `writeCheckpoint` argument if developers use custom write checkpoints. ``` diff @@ -12,6 +12,31 @@ guard let finalBatch = try await powersync.getCrudBatch(limit: 100) else { ``` * Fix reported progress around compactions / defrags on the sync service. * Use version `0.4.0` of the PowerSync core extension, which improves sync performance. +* Add a new sync client implementation written in Rust instead of Kotlin. While this client is still + experimental, we intend to make it the default in the future. The main benefit of this client is + faster sync performance, but upcoming features will also require this client. We encourage + interested users to try it out by opting in to experimental APIs and passing options when + connecting: + ```Swift + @_spi(PowerSyncExperimental) import PowerSync + + try await db.connect(connector: connector, options: ConnectOptions( + newClientImplementation: true, + )) + ``` + Switching between the clients can be done at any time without compatibility issues. If you run + into issues with the new client, please reach out to us! +* In addition to HTTP streams, the Swift SDK also supports fetching sync instructions from the + PowerSync service in a binary format. This requires the new sync client, and can then be enabled + on the sync options: + ```Swift + @_spi(PowerSyncExperimental) import PowerSync + + try await db.connect(connector: connector, options: ConnectOptions( + newClientImplementation: true, + connectionMethod: .webSocket, + )) + ``` ## 1.1.0 diff --git a/Package.swift b/Package.swift index 77bdece..0b130bb 100644 --- a/Package.swift +++ b/Package.swift @@ -27,8 +27,8 @@ if let kotlinSdkPath = localKotlinSdkOverride { // Not using a local build, so download from releases conditionalTargets.append(.binaryTarget( name: "PowerSyncKotlin", - url: "https://github.com/powersync-ja/powersync-kotlin/releases/download/v1.1.1/PowersyncKotlinRelease.zip", - checksum: "780437e25d41e46c2c1f555adcf330436f185d3663ef442da7141381d9c0495b" + url: "https://github.com/powersync-ja/powersync-kotlin/releases/download/v1.2.0/PowersyncKotlinRelease.zip", + checksum: "7454481a245b46b1b63a42419ec27f88f2fcb7fba9b763e3085cb49db59dfd58" )) } diff --git a/Sources/PowerSync/Kotlin/KotlinPowerSyncDatabaseImpl.swift b/Sources/PowerSync/Kotlin/KotlinPowerSyncDatabaseImpl.swift index bdc5893..ccfcd3a 100644 --- a/Sources/PowerSync/Kotlin/KotlinPowerSyncDatabaseImpl.swift +++ b/Sources/PowerSync/Kotlin/KotlinPowerSyncDatabaseImpl.swift @@ -52,12 +52,21 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol { ) let resolvedOptions = options ?? ConnectOptions() + let useWebsockets = switch (resolvedOptions.connectionMethod) { + case .http: false + case .webSocket: true + } try await kotlinDatabase.connect( connector: connectorAdapter, crudThrottleMs: Int64(resolvedOptions.crudThrottle * 1000), retryDelayMs: Int64(resolvedOptions.retryDelay * 1000), - params: resolvedOptions.params.mapValues { $0.toKotlinMap() } + params: resolvedOptions.params.mapValues { $0.toKotlinMap() }, + options: createSyncOptions( + newClient: resolvedOptions.newClientImplementation, + webSocket: useWebsockets, + userAgent: "PowerSync Swift SDK" + ) ) } diff --git a/Sources/PowerSync/Protocol/PowerSyncDatabaseProtocol.swift b/Sources/PowerSync/Protocol/PowerSyncDatabaseProtocol.swift index 6f26f9e..c8b63c2 100644 --- a/Sources/PowerSync/Protocol/PowerSyncDatabaseProtocol.swift +++ b/Sources/PowerSync/Protocol/PowerSyncDatabaseProtocol.swift @@ -34,7 +34,22 @@ public struct ConnectOptions { /// ] /// ``` public var params: JsonParam + + /// Uses a new sync client implemented in Rust instead of the one implemented in Kotlin. + /// + /// The new client is more efficient and will become the default in the future, but is still marked as experimental for now. + /// We encourage interested users to try the new client. + @_spi(PowerSyncExperimental) + public var newClientImplementation: Bool + /// The connection method used to connect to the Powersync service. + /// + /// The default method is ``ConnectionMethod/http``. Using ``ConnectionMethod/webSocket(_:)`` can + /// improve performance as a more efficient binary protocol is used. However, using the websocket connection method + /// requires enabling ``ConnectOptions/newClientImplementation``. + @_spi(PowerSyncExperimental) + public var connectionMethod: ConnectionMethod + /// Initializes a `ConnectOptions` instance with optional values. /// /// - Parameters: @@ -49,9 +64,32 @@ public struct ConnectOptions { self.crudThrottle = crudThrottle self.retryDelay = retryDelay self.params = params + self.newClientImplementation = false + self.connectionMethod = .http + } + + /// Initializes a ``ConnectOptions`` instance with optional values, including experimental options. + @_spi(PowerSyncExperimental) + public init( + crudThrottle: TimeInterval = 1, + retryDelay: TimeInterval = 5, + params: JsonParam = [:], + newClientImplementation: Bool = false, + connectionMethod: ConnectionMethod = .http + ) { + self.crudThrottle = crudThrottle + self.retryDelay = retryDelay + self.params = params + self.newClientImplementation = newClientImplementation + self.connectionMethod = connectionMethod } } +@_spi(PowerSyncExperimental) +public enum ConnectionMethod { + case http + case webSocket +} /// A PowerSync managed database. ///