@@ -38,7 +38,8 @@ final class StreamingSyncClient: Sendable {
3838
3939 private func uploadLoop( signals: SyncSignals ) async throws {
4040 // TODO: Replace with better watch mechanism once we've dropped the Kotlin dependency and can use onChange.
41- let watch = try db. watch ( sql: " SELECT 1 FROM ps_crud LIMIT 1 " , parameters: [ ] , mapper: { _ in ( ) } )
41+ let options = WatchOptions ( sql: " SELECT 1 FROM ps_crud LIMIT 1 " , throttle: options. crudThrottle, mapper: { _ in ( ) } )
42+ let watch = try db. watch ( options: options)
4243 . dropFirst ( ) // Skip initial result, we just want to watch changes
4344 . map { _ in ( ) }
4445 let allTriggers = AsyncAlgorithms . merge ( watch, signals. signalCrudUpload. subscribe ( ) )
@@ -131,18 +132,21 @@ The next upload iteration will be delayed.
131132 try tx. execute ( sql: " UPDATE ps_buckets SET target_op = CAST(? AS INTEGER) WHERE name = '$local' " , parameters: [ opId] )
132133 }
133134 }
134-
135+
136+ private func handleCommonResponseErrors( response: HTTPURLResponse ) async {
137+ if response. statusCode == 401 {
138+ await self . invalidateCredentials ( )
139+ }
140+ }
141+
135142 private func getWriteCheckpoint( ) async throws -> String {
136143 let clientId = try await db. get ( " SELECT powersync_client_id() " ) { try $0. getString ( index: 0 ) }
137144 let ( _, request) = try await authenticatedRequest { endpoint in
138145 endpoint. path += " /write-checkpoint2.json "
139146 endpoint. queryItems = [ . init( name: " client_id " , value: clientId) ]
140147 }
141148 let ( response, data) = try await httpClient. readFully ( request: request)
142-
143- if response. statusCode == 401 {
144- await self . invalidateCredentials ( )
145- }
149+ await self . handleCommonResponseErrors ( response: response)
146150 if response. statusCode != 200 {
147151 throw PowerSyncError . operationFailed ( message: " Error getting write checkpoint: \( response. statusCode) " )
148152 }
@@ -209,14 +213,23 @@ The next upload iteration will be delayed.
209213 httpRequest. setValue ( " application/x-ndjson " , forHTTPHeaderField: " Accept " )
210214 httpRequest. httpBody = try StreamingSyncClient . jsonEncoder. encode ( request)
211215
212- let ( response, stream) = try await httpClient. receiveSyncLines ( request: httpRequest)
213- if response. statusCode == 401 {
214- await invalidateCredentials ( )
216+ let response : HTTPURLResponse
217+ let stream : any SyncLineResponse
218+ do {
219+ ( response, stream) = try await httpClient. receiveSyncLines ( request: httpRequest)
220+ } catch {
221+ if let responseError = error as? UnexpectedResponseError {
222+ await handleCommonResponseErrors ( response: responseError. response)
223+ }
224+
225+ throw error
215226 }
227+
228+ await handleCommonResponseErrors ( response: response)
216229 if response. statusCode != 200 {
217230 throw PowerSyncError . operationFailed ( message: " POST \( url) failed with status code \( response. statusCode) " )
218231 }
219-
232+
220233 return ControlInvocationsFromStream ( sequence: stream)
221234 }
222235
0 commit comments